Class NumberUtils

java.lang.Object
org.daiitech.naftah.builtin.utils.NumberUtils

public final class NumberUtils extends Object
Utility class for dynamically parsing and performing arithmetic operations on various numeric types. Supports Byte, Short, Integer, Long, Float, Double, BigInteger, and BigDecimal.
Author:
Chakib Daii
  • Field Details

    • LONG_MIN

      private static final BigInteger LONG_MIN
    • LONG_MAX

      private static final BigInteger LONG_MAX
  • Constructor Details

    • NumberUtils

      private NumberUtils()
      Private constructor to prevent instantiation. Always throws a NaftahBugError when called.
  • Method Details

    • parseDynamicNumber

      public static Number parseDynamicNumber(Object object)
      Parses a dynamic numeric value from the given Object.

      If the object is already an instance of Number, it is returned as-is. If the object is a String, it is parsed using parseDynamicNumber(String). Otherwise, an exception is thrown indicating that the value is not a valid numeric type.

      Parameters:
      object - the object to parse as a numeric value; expected to be either a Number or a String.
      Returns:
      the parsed Number.
      Throws:
      NaftahBugError - if the object is not a valid numeric value.
      See Also:
    • parseDynamicNumber

      public static Number parseDynamicNumber(String text)
      Parses a string into the most appropriate Number type.
      • Parses decimal numbers (with dot or exponent) as Float, Double, or BigDecimal (in that order).
      • Parses whole numbers as Byte, Short, Integer, Long, or BigInteger (in that order).
      Parameters:
      text - the input numeric string
      Returns:
      the parsed Number
      Throws:
      RuntimeException - if parsing fails or if value is NaN or infinite
    • tryParseDynamicNumber

      public static Number tryParseDynamicNumber(String text)
      Attempts to parse a given text into a Number using dynamic number parsing logic.

      This method first checks if the input text is "truthy" (i.e., not null, empty, or false-like). If the text is not truthy, it returns a dynamic number with value 0.

      If the text is truthy, it tries to parse it using parseDynamicNumber(String, int, String). If parsing fails due to any exception or NaftahBugError, it returns a dynamic number with value Double.NaN.

      Parameters:
      text - the string to be parsed
      Returns:
      a Number parsed from the input text, or 0 if the text is not truthy, or Double.NaN if parsing fails
    • parseDynamicNumber

      public static Number parseDynamicNumber(String text, DynamicNumber radix, String originalText)
      Parses a string into the most appropriate Number type using the specified radix.

      This method supports custom bases for whole numbers (e.g., base 2 to base 36), while floating-point numbers are always treated as base-10 (radix is ignored).

      • If the string represents a floating-point number (contains '.' or scientific notation), it will be parsed as Float, Double, or BigDecimal.
      • Otherwise, it is parsed using the given radix into Byte, Short, Integer, Long, or BigInteger depending on value range.
      Parameters:
      text - the numeric string to parse
      radix - the base to use for whole number parsing (from 2 to 36)
      originalText - the original string (in case of base numbers after using
      Returns:
      the parsed Number instance (type chosen dynamically)
      Throws:
      RuntimeException - if parsing fails, the radix is invalid, or result is NaN/infinite
    • parseDynamicNumber

      public static Number parseDynamicNumber(String text, int radix, String originalText)
      Parses a string into the most appropriate Number type using the specified radix.

      This method supports custom bases for whole numbers (e.g., base 2 to base 36), while floating-point numbers are always treated as base-10 (radix is ignored).

      • If the string represents a floating-point number (contains '.' or scientific notation), it will be parsed as Float, Double, or BigDecimal.
      • Otherwise, it is parsed using the given radix into Byte, Short, Integer, Long, or BigInteger depending on value range.
      Parameters:
      text - the numeric string to parse
      radix - the base to use for whole number parsing (from 2 to 36)
      originalText - the original string (in case of base numbers after using
      Returns:
      the parsed Number instance (type chosen dynamically)
      Throws:
      RuntimeException - if parsing fails, the radix is invalid, or result is NaN/infinite
    • convertNumberToTargetClass

      public static <T extends Number> T convertNumberToTargetClass(Number number, Class<T> targetClass) throws IllegalArgumentException
      Convert the given number into an instance of the given target class.
      Parameters:
      number - the number to convert
      targetClass - the target class to convert to
      Returns:
      the converted number
      Throws:
      IllegalArgumentException - if the target class is not supported (i.e. not a standard Number subclass as included in the JDK)
      See Also:
    • checkedLongValue

      private static long checkedLongValue(Number number, Class<? extends Number> targetClass)
      Check for a BigInteger/BigDecimal long overflow before returning the given number as a long value.
      Parameters:
      number - the number to convert
      targetClass - the target class to convert to
      Returns:
      the long value, if convertible without overflow
      Throws:
      IllegalArgumentException - if there is an overflow
      See Also:
    • add

      public static <T extends Number> Number add(T left, T right)
      Adds two Number values.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      left - left operand
      right - right operand
      Returns:
      the result of addition
    • add

      public static Number add(Object left, Object right)
      Adds two numeric values represented as strings.
      Parameters:
      left - left operand
      right - right operand
      Returns:
      the result of addition
    • add

      public static Number add(DynamicNumber dx, DynamicNumber dy)
      Adds two DynamicNumber instances with type promotion.
      Parameters:
      dx - left operand
      dy - right operand
      Returns:
      the result of addition
    • subtract

      public static <T extends Number> Number subtract(T left, T right)
      Subtracts two Number values.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      left - left operand
      right - right operand
      Returns:
      the result of subtraction
    • subtract

      public static Number subtract(Object left, Object right)
      Subtracts two numeric values represented as strings.
      Parameters:
      left - left operand
      right - right operand
      Returns:
      the result of subtraction
    • subtract

      public static Number subtract(DynamicNumber dx, DynamicNumber dy)
      Subtracts two DynamicNumber instances with type promotion.
      Parameters:
      dx - left operand
      dy - right operand
      Returns:
      the result of subtraction
    • multiply

      public static <T extends Number> Number multiply(T left, T right)
      Multiplies two Number values.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      left - left operand
      right - right operand
      Returns:
      the result of multiplication
    • multiply

      public static Number multiply(Object left, Object right)
      Multiplies two numeric values represented as strings.
      Parameters:
      left - left operand
      right - right operand
      Returns:
      the result of multiplication
    • multiply

      public static Number multiply(DynamicNumber dx, DynamicNumber dy)
      Multiplies two DynamicNumber instances with type promotion.
      Parameters:
      dx - left operand
      dy - right operand
      Returns:
      the result of multiplication
    • divide

      public static <T extends Number> Number divide(T left, T right)
      Divides two Number values.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      left - the dividend
      right - the divisor
      Returns:
      the result of division
    • divide

      public static Number divide(Object left, Object right)
      Divides two numeric values represented as strings.
      Parameters:
      left - the dividend
      right - the divisor
      Returns:
      the result of division
    • divide

      public static Number divide(DynamicNumber dx, DynamicNumber dy)
      Divides two DynamicNumber instances with type promotion.
      Parameters:
      dx - the dividend
      dy - the divisor
      Returns:
      the result of division
    • modulo

      public static <T extends Number> Number modulo(T left, T right)
      Computes the modulo (remainder) of two Number values.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      left - the dividend
      right - the divisor
      Returns:
      the result of division
    • modulo

      public static Number modulo(Object left, Object right)
      Computes the modulo (remainder) of two numeric values represented as strings.
      Parameters:
      left - the dividend
      right - the divisor
      Returns:
      the result of division
    • modulo

      public static Number modulo(DynamicNumber dx, DynamicNumber dy)
      Computes the modulo (remainder) of two DynamicNumber instances with type promotion.
      Parameters:
      dx - the dividend
      dy - the divisor
      Returns:
      the result of division
    • max

      public static <T extends Number> Number max(T left, T right)
      Returns the greater of two Number values.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      left - the first number
      right - the second number
      Returns:
      the greatest of left and right, as a Number
    • max

      public static Number max(Object left, Object right)
      Returns the greater of two numeric values represented as strings.
      Parameters:
      left - the first number
      right - the second number
      Returns:
      the greatest of left and right, as a Number
    • max

      public static Number max(DynamicNumber dx, DynamicNumber dy)
      Returns the greater of two DynamicNumber instances with type promotion.
      Parameters:
      dx - the first number
      dy - the second number
      Returns:
      the greatest of dx and dy, as a Number
    • min

      public static <T extends Number> Number min(T left, T right)
      Returns the lesser of two Number values.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      left - the first number
      right - the second number
      Returns:
      the least of left and right, as a Number
    • min

      public static Number min(Object left, Object right)
      Returns the lesser of two numeric values represented as strings.
      Parameters:
      left - the first number
      right - the second number
      Returns:
      the least of left and right, as a Number
    • min

      public static Number min(DynamicNumber dx, DynamicNumber dy)
      Returns the lesser of two DynamicNumber instances with type promotion.
      Parameters:
      dx - the first number
      dy - the second number
      Returns:
      the least of dx and dy, as a Number
    • pow

      public static <T extends Number> Number pow(T base, T exponent)
      Raises a number Number to the power of another.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      base - the base number
      exponent - the exponent
      Returns:
      the result of raising base to the power of exponent, as a Number
    • pow

      public static Number pow(Object base, double exponent)
      Raises a number represented as string to the power of another.
      Parameters:
      base - the base number
      exponent - the exponent
      Returns:
      the result of raising base to the power of exponent, as a Number
    • pow

      public static Number pow(DynamicNumber base, double exponent)
      Raises a number DynamicNumber to the power of another.
      Parameters:
      base - the base number
      exponent - the exponent
      Returns:
      the result of raising base to the power of exponent, as a Number
    • doPow

      private static Number doPow(Number base, double exponent)
      Performs exponentiation on a given Number base and a double exponent.

      This method converts the base to a double and uses Math.pow(double, double). If the result or base is NaN or Infinity, it falls back to powInvalidDouble(Number, double, double).

      Parameters:
      base - the numeric base (can be Integer, Double, BigInteger, etc.)
      exponent - the exponent to raise the base to
      Returns:
      the result of base ^ exponent, or a fallback value if the operation is invalid
    • powInvalidDouble

      private static Number powInvalidDouble(Number base, double baseDouble, double exponent)
      Fallback method for exponentiation when Math.pow(double, double) returns NaN or Infinity.

      Attempts to use type-specific power operations for BigInteger and BigDecimal. If the base is neither of those, or an exception occurs, returns a DynamicNumber containing the double representation of the base.

      Parameters:
      base - the original numeric base
      baseDouble - the double representation of the base
      exponent - the exponent used in the operation
      Returns:
      a fallback Number result for the invalid power operation
    • round

      public static <T extends Number> Number round(T x)
      Rounds the given number Number to the nearest integer.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      x - the number to round
      Returns:
      the rounded number
    • round

      public static Number round(Object x)
      Rounds the given number represented as string to the nearest integer.
      Parameters:
      x - the number to round
      Returns:
      the rounded number
    • round

      public static Number round(DynamicNumber dx)
      Rounds the given number DynamicNumber to the nearest integer.
      Parameters:
      dx - the number to round
      Returns:
      the rounded number
    • floor

      public static <T extends Number> Number floor(T x)
      Returns the largest integer less than or equal the given number Number to the nearest integer.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      x - the number to round
      Returns:
      the rounded number
    • floor

      public static Number floor(Object x)
      Returns the largest integer less than or equal the given number represented as string to the nearest integer.
      Parameters:
      x - the number to round
      Returns:
      the rounded number
    • floor

      public static Number floor(DynamicNumber dx)
      Returns the largest integer less than or equal the given number DynamicNumber to the nearest integer.
      Parameters:
      dx - the number to round
      Returns:
      the rounded number
    • ceil

      public static <T extends Number> Number ceil(T x)
      Returns the smallest integer greater than or equal the given number Number to the nearest integer.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      x - the number to apply ceiling to
      Returns:
      the ceiling value
    • ceil

      public static Number ceil(Object x)
      Returns the smallest integer greater than or equal the given number represented as string to the nearest integer.
      Parameters:
      x - the number to apply ceiling to
      Returns:
      the ceiling value
    • ceil

      public static Number ceil(DynamicNumber dx)
      Returns the smallest integer greater than or equal the given number DynamicNumber to the nearest integer.
      Parameters:
      dx - the number to apply ceiling to
      Returns:
      the ceiling value
    • negate

      public static <T extends Number> Number negate(T x)
      Returns the negation of the given number Number.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      x - the number to negate
      Returns:
      the negated number
    • negate

      public static Number negate(Object x)
      Returns the negation of the given number represented as string.
      Parameters:
      x - the number to negate
      Returns:
      the negated number
    • negate

      public static Number negate(DynamicNumber dx)
      Returns the negation of the given number DynamicNumber.
      Parameters:
      dx - the number to negate
      Returns:
      the negated number
    • sqrt

      public static <T extends Number> Number sqrt(T x)
      Returns the square root of the given number Number.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      x - the number to compute the square root of
      Returns:
      the square root of the number
    • sqrt

      public static Number sqrt(Object x)
      Returns the square root of the given number represented as string.
      Parameters:
      x - the number to compute the square root of
      Returns:
      the square root of the number
    • sqrt

      public static Number sqrt(DynamicNumber dx)
      Returns the square root of the given number DynamicNumber.
      Parameters:
      dx - the number to compute the square root of
      Returns:
      the square root of the number
    • abs

      public static <T extends Number> Number abs(T x)
      Returns the absolute value of the given number Number.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      x - the number to compute the absolute value of
      Returns:
      the absolute value of the number
    • abs

      public static Number abs(Object x)
      Returns the absolute value of the given number represented as string.
      Parameters:
      x - the number to compute the absolute value of
      Returns:
      the absolute value of the number
    • abs

      public static Number abs(DynamicNumber dx)
      Returns the absolute value of the given number DynamicNumber.
      Parameters:
      dx - the number to compute the absolute value of
      Returns:
      the absolute value of the number
    • signum

      public static <T extends Number> int signum(T x)
      Returns the signum of the given number Number.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      x - the number to compute the signum of
      Returns:
      -1 if the number is negative, 0 if zero, and 1 if positive
    • signum

      public static int signum(Object x)
      Returns the signum of the given number represented as string.
      Parameters:
      x - the number to compute the signum of
      Returns:
      -1 if the number is negative, 0 if zero, and 1 if positive
    • signum

      public static int signum(DynamicNumber dx)
      Returns the signum of the given number DynamicNumber.
      Parameters:
      dx - the number to compute the signum of
      Returns:
      -1 if the number is negative, 0 if zero, and 1 if positive
    • isZero

      public static <T extends Number> boolean isZero(T x)
      Checks if the given number Number is zero.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      x - the number to check
      Returns:
      true if the number is zero; false otherwise
    • isZero

      public static boolean isZero(Object x)
      Checks if the given number is zero represented as string.
      Parameters:
      x - the number to check
      Returns:
      true if the number is zero; false otherwise
    • isZero

      public static boolean isZero(DynamicNumber dx)
      Checks if the given number DynamicNumber is zero.
      Parameters:
      dx - the number to check
      Returns:
      true if the number is zero; false otherwise
    • equals

      public static <T extends Number> boolean equals(T left, T right)
      Checks if two numbers Number are equal.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      left - the first number
      right - the second number
      Returns:
      true if left and right are equal in value; false otherwise
    • equals

      public static boolean equals(Object left, Object right)
      Checks if two numbers, represented as strings, are equal.
      Parameters:
      left - the first number
      right - the second number
      Returns:
      true if left and right are equal in value; false otherwise
    • equals

      public static boolean equals(DynamicNumber dx, DynamicNumber dy)
      Checks if two numbers DynamicNumber are equal.
      Parameters:
      dx - the first number
      dy - the second number
      Returns:
      true if dx and dy are equal in value; false otherwise
    • compare

      public static <T extends Number> int compare(T left, T right)
      Compares two numbers Number.
      Type Parameters:
      T - concrete type that extends @Number
      Parameters:
      left - the first number
      right - the second number
      Returns:
      a negative integer if left < right; zero if left == right; a positive integer if left > right
    • compare

      public static int compare(Object left, Object right)
      Compares two numbers, represented as strings.
      Parameters:
      left - the first number
      right - the second number
      Returns:
      a negative integer if left < right; zero if left == right; a positive integer if left > right
    • compare

      public static int compare(DynamicNumber dx, DynamicNumber dy)
      Compares two numbers DynamicNumber.
      Parameters:
      dx - the first number
      dy - the second number
      Returns:
      a negative integer if dx < dy; zero if dx == dy; a positive integer if dx > dy
    • and

      public static <T extends Number> Number and(T left, T right)
      Performs a bitwise AND operation between two Number values of the same type.

      This method wraps both input numbers in DynamicNumber, then delegates the operation to and(DynamicNumber, DynamicNumber). It supports all types that can be safely converted into DynamicNumber and that allow bitwise operations.

      Type Parameters:
      T - the type of the input numbers, which must extend Number.
      Parameters:
      left - the first operand.
      right - the second operand.
      Returns:
      the result of the bitwise AND operation as a Number.
      Throws:
      NaftahBugError - if the underlying number types do not support bitwise operations.
      See Also:
    • and

      public static Number and(Object left, Object right)
      Performs a bitwise AND operation between two dynamically-typed numeric values.

      This method accepts arbitrary Object inputs, attempts to wrap them as DynamicNumber instances, and delegates the bitwise operation to and(DynamicNumber, DynamicNumber). It is useful in dynamic or loosely-typed contexts where inputs may be Number, String, or other types.

      Parameters:
      left - the first operand; expected to be convertible to a DynamicNumber.
      right - the second operand; expected to be convertible to a DynamicNumber.
      Returns:
      the result of the bitwise AND operation as a Number.
      Throws:
      NaftahBugError - if either input is not a valid number or if bitwise operations are not supported on the types.
      See Also:
    • and

      public static Number and(DynamicNumber dx, DynamicNumber dy)
      Performs a bitwise AND operation on the given numbers DynamicNumber.
      Parameters:
      dx - the first number
      dy - the first number
      Returns:
      the number representing left & right
    • or

      public static <T extends Number> Number or(T left, T right)
      Performs a bitwise OR operation between two Number values of the same type.

      Both operands are converted to DynamicNumber, and the operation is delegated to or(DynamicNumber, DynamicNumber). This method is useful when working with strongly typed numeric values that support bitwise logic (e.g., integers).

      Type Parameters:
      T - the type of the input numbers, extending Number.
      Parameters:
      left - the first operand.
      right - the second operand.
      Returns:
      the result of the bitwise OR operation as a Number.
      Throws:
      NaftahBugError - if bitwise operations are not supported on the operand types.
      See Also:
    • or

      public static Number or(Object left, Object right)
      Performs a bitwise OR operation between two dynamically-typed numeric values.

      This method accepts arbitrary Object inputs, converts them to DynamicNumber, and delegates the operation to or(DynamicNumber, DynamicNumber). It is designed for dynamic contexts where the input types may vary at runtime.

      Parameters:
      left - the first operand; must be convertible to a DynamicNumber.
      right - the second operand; must be convertible to a DynamicNumber.
      Returns:
      the result of the bitwise OR operation as a Number.
      Throws:
      NaftahBugError - if either operand is not a valid numeric value or bitwise operations are not supported.
      See Also:
    • or

      public static Number or(DynamicNumber dx, DynamicNumber dy)
      Performs a bitwise OR operation on the given numbers DynamicNumber.
      Parameters:
      dx - the first number
      dy - the first number
      Returns:
      the number representing left | right
    • xor

      public static <T extends Number> Number xor(T left, T right)
      Performs a bitwise XOR (exclusive OR) operation between two Number values of the same type.

      Both operands are wrapped as DynamicNumber instances, and the operation is delegated to xor(DynamicNumber, DynamicNumber). This method supports bitwise XOR on numeric types that allow such operations (typically integers).

      Type Parameters:
      T - the type of the input numbers, extending Number.
      Parameters:
      left - the first operand.
      right - the second operand.
      Returns:
      the result of the bitwise XOR operation as a Number.
      Throws:
      NaftahBugError - if the operand types do not support bitwise operations.
      See Also:
    • xor

      public static Number xor(Object left, Object right)
      Performs a bitwise XOR (exclusive OR) operation between two dynamically-typed numeric values.

      This method accepts any Object inputs, converts them to DynamicNumber instances, and delegates the operation to xor(DynamicNumber, DynamicNumber). It is suitable for dynamic contexts where inputs may vary in type (e.g., Number, String, etc.).

      Parameters:
      left - the first operand; must be convertible to a DynamicNumber.
      right - the second operand; must be convertible to a DynamicNumber.
      Returns:
      the result of the bitwise XOR operation as a Number.
      Throws:
      NaftahBugError - if either input is not a valid numeric type or does not support bitwise operations.
      See Also:
    • xor

      public static Number xor(DynamicNumber dx, DynamicNumber dy)
      Performs a bitwise XOR operation on the given numbers DynamicNumber.
      Parameters:
      dx - the first number
      dy - the first number
      Returns:
      the number representing left ^ right
    • not

      public static <T extends Number> Number not(T x)
      Performs a bitwise NOT (inversion) operation on a numeric value.

      The input number is wrapped as a DynamicNumber, and the operation is delegated to not(DynamicNumber). This method supports numeric types that allow bitwise operations (typically integers).

      Type Parameters:
      T - the type of the input number, extending Number.
      Parameters:
      x - the number to invert.
      Returns:
      the result of the bitwise NOT operation as a Number.
      Throws:
      NaftahBugError - if the number type does not support bitwise operations.
      See Also:
    • not

      public static Number not(Object x)
      Performs a bitwise NOT (inversion) operation on a dynamically-typed numeric value.

      This method accepts any Object that can be converted to a DynamicNumber, and delegates the operation to not(DynamicNumber). It is intended for use in dynamic contexts where the input type may vary.

      Parameters:
      x - the value to invert; must be convertible to a DynamicNumber.
      Returns:
      the result of the bitwise NOT operation as a Number.
      Throws:
      NaftahBugError - if the input is not a valid numeric value or does not support bitwise operations.
      See Also:
    • not

      public static Number not(DynamicNumber dx)
      Performs a bitwise NOT operation on the given number DynamicNumber.
      Parameters:
      dx - the number to apply bitwise NOT operation to
      Returns:
      the number representing ~x
    • shiftLeft

      public static <T extends Number> Number shiftLeft(T x, T positions)
      Performs a left bitwise shift on a numeric value by the specified number of positions.

      The input number is wrapped as a DynamicNumber, and the shift operation is delegated to shiftLeft(DynamicNumber, int). This method is suitable for statically typed Number values that support bitwise operations (typically integer types).

      Type Parameters:
      T - the type of the input number, extending Number.
      Parameters:
      x - the number to shift.
      positions - the number of bit positions to shift to the left; must be non-negative.
      Returns:
      the result of the left shift operation as a Number.
      Throws:
      NaftahBugError - if the number type does not support bitwise operations.
      IllegalArgumentException - if the shift amount is negative or exceeds allowed bounds.
      See Also:
    • shiftLeft

      public static Number shiftLeft(Object x, int positions)
      Performs a left bitwise shift on a dynamically-typed numeric value by the specified number of positions.

      This method accepts any Object that can be converted to a DynamicNumber, and delegates the shift operation to shiftLeft(DynamicNumber, int). It is designed for use in dynamic or loosely typed contexts.

      Parameters:
      x - the value to shift; must be convertible to a DynamicNumber.
      positions - the number of bit positions to shift to the left; must be non-negative.
      Returns:
      the result of the left shift operation as a Number.
      Throws:
      NaftahBugError - if the input is not a valid numeric value or does not support bitwise operations.
      IllegalArgumentException - if the shift amount is negative or exceeds allowed bounds.
      See Also:
    • shiftLeft

      public static Number shiftLeft(DynamicNumber dx, int positions)
      Shifts the given number DynamicNumber to the left (signed shift).

      This is equivalent to multiplying the value by 2^n.

      Parameters:
      dx - the number to shift
      positions - the number of bits to shift to the left; must be non-negative
      Returns:
      the result of value << n
    • shiftLeft

      public static BigInteger shiftLeft(BigInteger bigInteger, int positions)
      Performs a left bitwise shift on a BigInteger value by the specified number of positions, with overflow checking against 64-bit long bounds.

      This method ensures that the shift will not produce a value that exceeds the range of a 64-bit signed integer, and throws an exception if overflow is detected.

      Parameters:
      bigInteger - the BigInteger value to shift.
      positions - the number of bit positions to shift to the left; must be non-negative.
      Returns:
      a new BigInteger representing the result of the shift.
      Throws:
      NaftahBugError - if the shift amount is invalid (e.g., negative or too large).
      ArithmeticException - if the shift would cause overflow beyond long range.
      See Also:
    • shiftRight

      public static <T extends Number> Number shiftRight(T x, T positions)
      Performs a right bitwise shift on a numeric value by the specified number of positions.

      The input value is converted to a DynamicNumber, and the operation is delegated to shiftRight(DynamicNumber, int). This operation is safe and does not cause overflow.

      Type Parameters:
      T - the type of the input number, extending Number.
      Parameters:
      x - the number to shift.
      positions - the number of bit positions to shift to the right; must be non-negative.
      Returns:
      the result of the right shift operation as a Number.
      Throws:
      NaftahBugError - if the number type does not support bitwise operations.
      IllegalArgumentException - if the shift amount is negative.
      See Also:
    • shiftRight

      public static Number shiftRight(Object x, int positions)
      Performs a right bitwise shift on a dynamically-typed numeric value by the specified number of positions.

      This method accepts any Object that can be converted to a DynamicNumber, and delegates the operation to shiftRight(DynamicNumber, int). It is designed for use in dynamic contexts where the input type may vary at runtime.

      Parameters:
      x - the value to shift; must be convertible to a DynamicNumber.
      positions - the number of bit positions to shift to the right; must be non-negative.
      Returns:
      the result of the right shift operation as a Number.
      Throws:
      NaftahBugError - if the input is not a valid numeric value or does not support bitwise operations.
      IllegalArgumentException - if the shift amount is negative.
      See Also:
    • shiftRight

      public static Number shiftRight(DynamicNumber dx, int positions)
      Shifts the given number DynamicNumber to the right (signed shift).

      This is equivalent to dividing the value by 2^n, with sign extension.

      Parameters:
      dx - the number to shift
      positions - the number of bits to shift to the right; must be non-negative
      Returns:
      the result of value >> n
    • unsignedShiftRight

      public static <T extends Number> Number unsignedShiftRight(T x, T positions)
      Performs an unsigned (logical) right bitwise shift on a numeric value by the specified number of positions.

      The input number is converted to a DynamicNumber, and the operation is delegated to unsignedShiftRight(DynamicNumber, int). This shift fills the left bits with zeros regardless of sign.

      Type Parameters:
      T - the type of the input number, extending Number.
      Parameters:
      x - the number to shift.
      positions - the number of bit positions to shift to the right; must be non-negative.
      Returns:
      the result of the unsigned right shift operation as a Number.
      Throws:
      NaftahBugError - if the number type does not support bitwise operations.
      IllegalArgumentException - if the shift amount is negative.
      See Also:
    • unsignedShiftRight

      public static Number unsignedShiftRight(Object x, int positions)
      Performs an unsigned (logical) right bitwise shift on a dynamically-typed numeric value by the specified number of positions.

      This method accepts any Object convertible to DynamicNumber, and delegates the operation to unsignedShiftRight(DynamicNumber, int).

      Parameters:
      x - the value to shift; must be convertible to a DynamicNumber.
      positions - the number of bit positions to shift to the right; must be non-negative.
      Returns:
      the result of the unsigned right shift operation as a Number.
      Throws:
      NaftahBugError - if the input is not a valid numeric value or does not support bitwise operations.
      IllegalArgumentException - if the shift amount is negative.
      See Also:
    • unsignedShiftRight

      public static Number unsignedShiftRight(DynamicNumber dx, int positions)
      Shifts the given number DynamicNumber to the right (unsigned shift).

      This is equivalent to dividing the value by 2^n, with sign extension.

      Parameters:
      dx - the number to shift
      positions - the number of bits to shift to the right; must be non-negative
      Returns:
      the result of an unsigned right shift (zero-fill) of value by n bits
    • preIncrement

      public static <T extends Number> Number preIncrement(T x)
      Performs a pre-increment operation on a numeric value.

      The input number is wrapped as a DynamicNumber, and the increment operation is delegated to preIncrement(DynamicNumber).

      Type Parameters:
      T - the type of the input number, extending Number.
      Parameters:
      x - the number to increment.
      Returns:
      the result of the pre-increment operation as a Number.
      Throws:
      NaftahBugError - if the input type is unsupported for arithmetic operations.
      See Also:
    • preIncrement

      public static Number preIncrement(Object x)
      Performs a pre-increment operation on a dynamically-typed numeric value.

      This method accepts any Object convertible to a DynamicNumber and delegates the increment operation to preIncrement(DynamicNumber).

      Parameters:
      x - the value to increment; must be convertible to DynamicNumber.
      Returns:
      the result of the pre-increment operation as a Number.
      Throws:
      NaftahBugError - if the input is not a valid numeric value or unsupported for arithmetic.
      See Also:
    • preIncrement

      public static Number preIncrement(DynamicNumber dx)
      Performs a pre-increment operation on the given DynamicNumber instance.

      This method handles numeric overflow by promoting the underlying number type to a larger or more precise numeric type when the maximum value is reached:

      • Byte and Short promote to Integer.
      • Integer promotes to Long.
      • Long promotes to BigInteger.
      • Float promotes to Double.
      • Double promotes to BigDecimal.

      For BigInteger and BigDecimal, it simply adds one without promotion. If no overflow occurs, it increments normally.

      Parameters:
      dx - the DynamicNumber to increment.
      Returns:
      the incremented number as a Number.
      Throws:
      NaftahBugError - if the underlying numeric type is not supported.
    • postIncrement

      public static <T extends Number> Number postIncrement(T x)
      Performs a post-increment operation on a numeric value.

      The input number is wrapped as a DynamicNumber, and the increment operation is delegated to postIncrement(DynamicNumber). The returned value is the original value before the increment.

      Type Parameters:
      T - the type of the input number, extending Number.
      Parameters:
      x - the number to increment.
      Returns:
      the original value before increment as a Number.
      Throws:
      NaftahBugError - if the input type is unsupported for arithmetic operations.
      See Also:
    • postIncrement

      public static Number postIncrement(Object x)
      Performs a post-increment operation on a dynamically-typed numeric value.

      This method accepts any Object convertible to a DynamicNumber and delegates the increment operation to postIncrement(DynamicNumber). The returned value is the original value before the increment.

      Parameters:
      x - the value to increment; must be convertible to DynamicNumber.
      Returns:
      the original value before increment as a Number.
      Throws:
      NaftahBugError - if the input is not a valid numeric value or unsupported for arithmetic.
      See Also:
    • postIncrement

      public static Number postIncrement(DynamicNumber dx)
      Performs a post-increment operation on the given DynamicNumber.

      The method returns the original value before incrementing. It handles overflow by promoting the underlying numeric type to a larger or more precise type when needed:

      • Byte and Short promote to Integer.
      • Integer promotes to Long.
      • Long promotes to BigInteger.
      • Float promotes to Double.
      • Double promotes to BigDecimal.

      For BigInteger and BigDecimal, it increments without promotion. If the type is unsupported, it throws a NaftahBugError.

      Parameters:
      dx - the DynamicNumber to post-increment.
      Returns:
      the original value before the increment as a Number.
      Throws:
      NaftahBugError - if the number type is unsupported.
    • preDecrement

      public static <T extends Number> Number preDecrement(T x)
      Performs a pre-decrement operation on a numeric value.

      The input number is wrapped as a DynamicNumber, and the decrement operation is delegated to preDecrement(DynamicNumber).

      Type Parameters:
      T - the type of the input number, extending Number.
      Parameters:
      x - the number to decrement.
      Returns:
      the result of the pre-decrement operation as a Number.
      Throws:
      NaftahBugError - if the input type is unsupported for arithmetic operations.
      See Also:
    • preDecrement

      public static Number preDecrement(Object x)
      Performs a pre-decrement operation on a dynamically-typed numeric value.

      This method accepts any Object convertible to a DynamicNumber and delegates the decrement operation to preDecrement(DynamicNumber).

      Parameters:
      x - the value to decrement; must be convertible to DynamicNumber.
      Returns:
      the result of the pre-decrement operation as a Number.
      Throws:
      NaftahBugError - if the input is not a valid numeric value or unsupported for arithmetic.
      See Also:
    • preDecrement

      public static Number preDecrement(DynamicNumber dx)
      Performs a pre-decrement operation on the given DynamicNumber.

      This method handles underflow by promoting the underlying number type to a larger or more precise numeric type when the minimum value is reached:

      • Byte and Short promote to Integer.
      • Integer promotes to Long.
      • Long promotes to BigInteger.
      • Float promotes to Double.
      • Double promotes to BigDecimal.
      For BigInteger and BigDecimal, it decrements without promotion. If no underflow occurs, it decrements normally.

      Parameters:
      dx - the DynamicNumber to decrement.
      Returns:
      the decremented number as a Number.
      Throws:
      NaftahBugError - if the underlying numeric type is not supported.
    • postDecrement

      public static <T extends Number> Number postDecrement(T x)
      Performs a post-decrement operation on a numeric value.

      The input number is wrapped as a DynamicNumber, and the decrement operation is delegated to postDecrement(DynamicNumber). The returned value is the original value before the decrement.

      Type Parameters:
      T - the type of the input number, extending Number.
      Parameters:
      x - the number to decrement.
      Returns:
      the original value before decrement as a Number.
      Throws:
      NaftahBugError - if the input type is unsupported for arithmetic operations.
      See Also:
    • postDecrement

      public static Number postDecrement(Object x)
      Performs a post-decrement operation on a dynamically-typed numeric value.

      This method accepts any Object convertible to a DynamicNumber and delegates the decrement operation to postDecrement(DynamicNumber). The returned value is the original value before the decrement.

      Parameters:
      x - the value to decrement; must be convertible to DynamicNumber.
      Returns:
      the original value before decrement as a Number.
      Throws:
      NaftahBugError - if the input is not a valid numeric value or unsupported for arithmetic.
      See Also:
    • postDecrement

      public static Number postDecrement(DynamicNumber dx)
      Performs a post-decrement operation on the given DynamicNumber.

      The method returns the original value before decrementing. It handles underflow by promoting the underlying numeric type to a larger or more precise type when needed:

      • Byte and Short promote to Integer.
      • Integer promotes to Long.
      • Long promotes to BigInteger.
      • Float promotes to Double.
      • Double promotes to BigDecimal.
      For BigInteger and BigDecimal, it decrements without promotion. If the type is unsupported, it throws a NaftahBugError.

      Parameters:
      dx - the DynamicNumber to post-decrement.
      Returns:
      the original value before the decrement as a Number.
      Throws:
      NaftahBugError - if the number type is unsupported.
    • unsignedShiftRight

      public static BigInteger unsignedShiftRight(BigInteger value, int n)
      Performs an unsigned (logical) right shift on a BigInteger.

      Unlike signed right shift, this operation fills high-order bits with zeros regardless of the sign of the BigInteger. Since BigInteger does not have a built-in unsigned right shift, this method emulates it for non-negative values. If the value is negative, the behavior may not match unsigned semantics in lower-level languages like Java's primitive types.

      Parameters:
      value - the BigInteger to shift; must not be null
      n - the number of bits to shift right; must be non-negative
      Returns:
      the result of shifting value to the right by n bits, using zero-fill
      Throws:
      NullPointerException - if value is null
      IllegalArgumentException - if n is negative
    • checkPrecision

      public static Number checkPrecision(String text, double d)
      Checks whether a double value retains full precision when parsed from the original string. Throws a NumberFormatException if precision is lost.
      Parameters:
      text - the original string representing the number
      d - the parsed double value
      Returns:
      the double value if precision is preserved
      Throws:
      NumberFormatException - if precision is lost during parsing
    • checkPrecision

      public static Number checkPrecision(String text, float f)
      Checks whether a float value retains full precision when parsed from the original string. Throws a NumberFormatException if precision is lost.
      Parameters:
      text - the original string representing the number
      f - the parsed float value
      Returns:
      the float value if precision is preserved
      Throws:
      NumberFormatException - if precision is lost during parsing
    • checkPrecision

      public static Number checkPrecision(BigDecimal expected, double d)
      Checks whether a double value matches the expected BigDecimal value. If not, returns the expected BigDecimal as a fallback.
      Parameters:
      expected - the expected BigDecimal value
      d - the double value to compare
      Returns:
      the original double if precise, otherwise the expected BigDecimal
    • checkPrecision

      public static Number checkPrecision(BigDecimal expected, float f)
      Checks whether a float value matches the expected BigDecimal value. If not, returns the expected BigDecimal as a fallback.
      Parameters:
      expected - the expected BigDecimal value
      f - the float value to compare
      Returns:
      the original float if precise, otherwise the expected BigDecimal
    • checkLeftShiftOverflow

      public static void checkLeftShiftOverflow(int size, long max, long min, BigInteger value, int positions)
      Checks for overflow when left-shifting a BigInteger value by a given number of bits.

      This method verifies that the shift amount is within valid bounds and that the value, when shifted, will not exceed the range of a 64-bit signed long. If an overflow condition is detected, an exception is thrown with a descriptive message.

      Parameters:
      size - the maximum allowed shift size (in bits). If set to -1, no upper bound check is performed.
      value - the BigInteger value to be shifted.
      positions - the number of bits to shift left; must be non-negative and less than size if size is not -1.
      Throws:
      NaftahBugError - if the shift amount is invalid (negative or out of range).
      ArithmeticException - if shifting the value would overflow the range of a long.
    • checkLeftShiftOverflow

      public static void checkLeftShiftOverflow(BigInteger value, int positions)
      Checks if left shift operation on the given BigInteger value by a number of positions would cause overflow according to the specified limits.

      This method delegates to the general checkLeftShiftOverflow(int, long, long, BigInteger, int, boolean) method with default size and limits (-1 means no limit).

      Parameters:
      value - the BigInteger value to be shifted left.
      positions - the number of bit positions to shift left.
      Throws:
      NaftahBugError - if the shift positions are invalid or if the shifted value would overflow.
    • checkLeftShiftOverflow

      public static void checkLeftShiftOverflow(int size, long max, long min, BigInteger value, int positions, boolean wrap)
      Checks if left shift operation on the given BigInteger value by a number of positions would cause overflow or underflow based on the provided limits and size.

      Throws NaftahBugError wrapping an ArithmeticException if overflow or underflow conditions are detected and wrap is true; otherwise throws the raw ArithmeticException.

      Parameters:
      size - the bit size of the type being shifted, or -1 if unknown/unbounded.
      max - the maximum allowed long value before shifting, or -1 if no maximum limit.
      min - the minimum allowed long value before shifting, or -1 if no minimum limit.
      value - the BigInteger value to be shifted.
      positions - the number of bits to shift left.
      wrap - if true, wraps any ArithmeticException in a NaftahBugError.
      Throws:
      NaftahBugError - if wrap is true and invalid shift or overflow/underflow detected.
      ArithmeticException - if wrap is false and invalid shift or overflow/underflow detected.
    • checkShiftPositions

      public static void checkShiftPositions(int size, int positions)
      Checks if the shift positions parameter is valid given the bit size of the type.

      Throws a NaftahBugError if the positions are invalid.

      Parameters:
      size - the bit size of the type being shifted, or -1 if unbounded.
      positions - the number of bit positions to shift.
      Throws:
      NaftahBugError - if positions is negative or exceeds size - 1.
    • checkShiftPositions

      public static Throwable checkShiftPositions(int size, int positions, boolean wrap)
      Validates the shift positions against the allowed range for a given bit size.

      Returns a wrapped NaftahBugError or raw ArithmeticException if invalid, or null if valid.

      Parameters:
      size - the bit size of the type being shifted, or -1 if unbounded.
      positions - the number of bits to shift.
      wrap - if true, returns a NaftahBugError wrapping the exception; otherwise raw.
      Returns:
      a Throwable representing the error if invalid, or null if valid.