Package: org.codehaus.groovy.runtime.typehandling

## [Java] Class NumberMath

- org.codehaus.groovy.runtime.typehandling.NumberMath

-     public abstract class NumberMath
      extends Object

  Stateless objects used to perform math on the various Number subclasses. Instances are required so that polymorphic calls work properly, but each subclass creates a singleton instance to minimize garbage. All methods must be thread-safe. The design goals of this class are as follows:

  1. Support a 'least surprising' math model to scripting language users. This means that exact, or decimal math should be used for default calculations. This scheme assumes that by default, groovy literals with decimal points are instantiated as BigDecimal objects rather than binary floating points (Float, Double).
  2. Do not force the appearance of exactness on a number that is by definition not guaranteed to be exact. In particular this means that if an operand in a NumberMath operation is a binary floating point number, ensure that the result remains a binary floating point number (i.e. never automatically promote a binary floating point number to a BigDecimal). This has the effect of preserving the expectations of binary floating point users and helps performance.
  3. Provide an implementation that is as close as practical to the Java 1.5 BigDecimal math model which implements precision based floating point decimal math (ANSI X3.274-1996 and ANSI X3.274-1996/AM 1-2000 (section 7.4).

- - ### Methods Summary

    Methods
    Type Params | Return Type | Name and description
    --- | --- | ---
    `` | `public static Number` | `abs(Number number)` Computes the absolute value of a number using its specific type's math operations.
    `` | `protected abstract Number` | `absImpl(Number number)` Computes the absolute value of a number.
    `` | `public static Number` | `add(Number left, Number right)` Adds two numbers using type promotion rules.
    `` | `public abstract Number` | `addImpl(Number left, Number right)` Adds two numbers.
    `` | `public static Number` | `and(Number left, Number right)` Bitwise AND operation on two integral numbers.
    `` | `protected Number` | `andImpl(Number left, Number right)` Bitwise AND of two numbers.
    `` | `public static Number` | `bitwiseNegate(Number left)` Bitwise negation (complement) of an integral number.
    `` | `protected Number` | `bitwiseNegateImpl(Number left)` Bitwise negation of a number.
    `` | `public static int` | `compareTo(Number left, Number right)` Compares two numbers using type promotion rules.
    `` | `public abstract int` | `compareToImpl(Number left, Number right)` Compares two numbers.
    `` | `protected UnsupportedOperationException` | `createUnsupportedException(String operation, Number left)` Creates an UnsupportedOperationException for an unsupported operation.
    `` | `public static Number` | `divide(Number left, Number right)` Divides two numbers using type promotion rules.
    `` | `public abstract Number` | `divideImpl(Number left, Number right)` Divides two numbers.
    `` | `public static NumberMath` | `getMath(Number left, Number right)` Determines which NumberMath instance to use for binary operations on two operands.
    `` | `public static Number` | `intdiv(Number left, Number right)` Integer division (without remainder) of two numbers.
    `` | `protected Number` | `intdivImpl(Number left, Number right)` Integer division of two numbers.
    `` | `public static boolean` | `isBigDecimal(Number number)` Tests whether a number is a BigDecimal.
    `` | `public static boolean` | `isBigInteger(Number number)` Tests whether a number is a BigInteger.
    `` | `public static boolean` | `isByte(Number number)` Tests whether a number is a Byte.
    `` | `public static boolean` | `isFloatingPoint(Number number)` Tests whether a number is a floating-point type (Float or Double).
    `` | `public static boolean` | `isInteger(Number number)` Tests whether a number is an Integer.
    `` | `public static boolean` | `isLong(Number number)` Tests whether a number is a Long.
    `` | `public static boolean` | `isShort(Number number)` Tests whether a number is a Short.
    `` | `public static Number` | `leftShift(Number left, Number right)` Left shift operation on integral numbers.
    `` | `protected Number` | `leftShiftImpl(Number left, Number right)` Left shift of a number.
    `` | `public static Number` | `mod(Number left, Number right)` Modulo operation on two numbers (for backwards compatibility).
    `` | `protected Number` | `modImpl(Number left, Number right)` Modulo of two numbers.
    `` | `public static Number` | `multiply(Number left, Number right)` Multiplies two numbers using type promotion rules.
    `` | `public abstract Number` | `multiplyImpl(Number left, Number right)` Multiplies two numbers.
    `` | `public static Number` | `or(Number left, Number right)` Bitwise OR operation on two integral numbers.
    `` | `protected Number` | `orImpl(Number left, Number right)` Bitwise OR of two numbers.
    `` | `public static Number` | `remainder(Number left, Number right)` Remainder operation on two numbers.
    `` | `protected Number` | `remainderImpl(Number left, Number right)` Remainder of two numbers.
    `` | `public static Number` | `rightShift(Number left, Number right)` Right shift operation on integral numbers.
    `` | `protected Number` | `rightShiftImpl(Number left, Number right)` Right shift of a number.
    `` | `public static Number` | `rightShiftUnsigned(Number left, Number right)` Unsigned right shift operation on integral numbers.
    `` | `protected Number` | `rightShiftUnsignedImpl(Number left, Number right)` Unsigned right shift of a number.
    `` | `public static Number` | `subtract(Number left, Number right)` Subtracts two numbers using type promotion rules.
    `` | `public abstract Number` | `subtractImpl(Number left, Number right)` Subtracts two numbers.
    `` | `public static BigDecimal` | `toBigDecimal(Number n)` Converts a number to a BigDecimal.
    `` | `public static BigInteger` | `toBigInteger(Number n)` Converts a number to a BigInteger.
    `` | `public static Number` | `unaryMinus(Number left)` Unary negation of a number.
    `` | `protected abstract Number` | `unaryMinusImpl(Number left)` Negates a number.
    `` | `public static Number` | `unaryPlus(Number left)` Unary plus (identity) operation on a number.
    `` | `protected abstract Number` | `unaryPlusImpl(Number left)` Returns the number as-is (unary plus/identity).
    `` | `public static Number` | `xor(Number left, Number right)` Bitwise XOR operation on two integral numbers.
    `` | `protected Number` | `xorImpl(Number left, Number right)` Bitwise XOR of two numbers.

  - ### Inherited Methods Summary

    Inherited Methods
    Methods inherited from class | Name
    --- | ---
    `class Object` | `equals, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- - ### Method Detail

    - #### public static Number abs(Number number)

      Computes the absolute value of a number using its specific type's math operations.

      Parameters:
        `number` - the number (must not be null)
      Returns:
        the absolute value using the appropriate NumberMath instance

    - #### protected abstract Number absImpl(Number number)

      Computes the absolute value of a number.

      Subclasses must implement this method according to type promotion hierarchy rules.

      Parameters:
        `number` - the operand
      Returns:
        the absolute value

    - #### public static Number add(Number left, Number right)

      Adds two numbers using type promotion rules.

      Parameters:
        `left` - the left operand
        `right` - the right operand
      Returns:
        the sum using the appropriate NumberMath instance

    - #### public abstract Number addImpl(Number left, Number right)

      Adds two numbers.

      Subclasses must implement this method according to type promotion hierarchy rules.

      Parameters:
        `left` - the left operand
        `right` - the right operand
      Returns:
        the sum

    - #### public static Number and(Number left, Number right)

      Bitwise AND operation on two integral numbers.

      throws:
        UnsupportedOperationException if operands are not integral types
      Parameters:
        `left` - the first operand
        `right` - the second operand
      Returns:
        the bitwise AND result

    - #### protected Number andImpl(Number left, Number right)

      Bitwise AND of two numbers.

      Default implementation throws UnsupportedOperationException. Subclasses supporting bitwise operations must override.

      throws:
        UnsupportedOperationException if not supported for this type
      Parameters:
        `left` - the first operand
        `right` - the second operand
      Returns:
        the bitwise AND result

    - #### public static Number bitwiseNegate(Number left)

      Bitwise negation (complement) of an integral number.

      throws:
        UnsupportedOperationException if operand is not integral
      Parameters:
        `left` - the operand (must be integral)
      Returns:
        the bitwise negation

    - #### protected Number bitwiseNegateImpl(Number left)

      Bitwise negation of a number.

      Default implementation throws UnsupportedOperationException. Subclasses supporting bitwise operations must override.

      throws:
        UnsupportedOperationException if not supported for this type
      Parameters:
        `left` - the operand
      Returns:
        the bitwise negation

    - #### public static int compareTo(Number left, Number right)

      Compares two numbers using type promotion rules.

      Parameters:
        `left` - the first number
        `right` - the second number
      Returns:
        a negative, zero, or positive int as left is less than, equal to, or greater than right

    - #### public abstract int compareToImpl(Number left, Number right)

      Compares two numbers.

      Subclasses must implement this method according to type promotion hierarchy rules.

      Parameters:
        `left` - the first number
        `right` - the second number
      Returns:
        negative, zero, or positive as left is less than, equal to, or greater than right

    - #### protected UnsupportedOperationException createUnsupportedException(String operation, Number left)

      Creates an UnsupportedOperationException for an unsupported operation.

      Parameters:
        `operation` - the name of the unsupported operation
        `left` - the operand
      Returns:
        a new UnsupportedOperationException

    - #### public static Number divide(Number left, Number right)

      Divides two numbers using type promotion rules.

      For floating-point operands, performs binary floating-point division. For integral types, delegates to BigDecimal division for exact results.

      throws:
        ArithmeticException if right is zero
      Parameters:
        `left` - the dividend
        `right` - the divisor
      Returns:
        the quotient using the appropriate NumberMath instance

    - #### public abstract Number divideImpl(Number left, Number right)

      Divides two numbers.

      Subclasses must implement this method according to type promotion hierarchy rules.

      Parameters:
        `left` - the dividend
        `right` - the divisor
      Returns:
        the quotient

    - #### public static NumberMath getMath(Number left, Number right)

      Determines which NumberMath instance to use for binary operations on two operands.

      Implements the type promotion matrix:

              bD bI  D  F  L  I
           bD bD bD  D  D bD bD
           bI bD bI  D  D bI bI
            D  D  D  D  D  D  D
            F  D  D  D  D  D  D
            L bD bI  D  D  L  L
            I bD bI  D  D  L  I

      Where: bD=BigDecimal, bI=BigInteger, D=Double, F=Float, L=Long, I=Integer

      Note: Byte, Character, and Short operands are pre-promoted to Integer. For division, if either operand is floating-point, the result is floating-point. Otherwise, the result is BigDecimal.

      Parameters:
        `left` - the left operand
        `right` - the right operand
      Returns:
        the appropriate NumberMath instance for these operands

    - #### public static Number intdiv(Number left, Number right)

      Integer division (without remainder) of two numbers.

      For BigInteger and integral types, performs exact integer division. For floating-point operands, delegates to FloatingPointMath.

      throws:
        UnsupportedOperationException if operands don't support integer division
      Parameters:
        `left` - the dividend
        `right` - the divisor
      Returns:
        the integer quotient

    - #### protected Number intdivImpl(Number left, Number right)

      Integer division of two numbers.

      Default implementation throws UnsupportedOperationException. Subclasses supporting integer division must override.

      throws:
        UnsupportedOperationException if not supported for this type
      Parameters:
        `left` - the dividend
        `right` - the divisor
      Returns:
        the integer quotient

    - #### public static boolean isBigDecimal(Number number)

      Tests whether a number is a BigDecimal.

      Parameters:
        `number` - the number to test
      Returns:
        true if the number is a BigDecimal

    - #### public static boolean isBigInteger(Number number)

      Tests whether a number is a BigInteger.

      Parameters:
        `number` - the number to test
      Returns:
        true if the number is a BigInteger

    - #### public static boolean isByte(Number number)

      Tests whether a number is a Byte.

      Parameters:
        `number` - the number to test
      Returns:
        true if the number is a Byte

    - #### public static boolean isFloatingPoint(Number number)

      Tests whether a number is a floating-point type (Float or Double).

      Parameters:
        `number` - the number to test
      Returns:
        true if the number is Float or Double

    - #### public static boolean isInteger(Number number)

      Tests whether a number is an Integer.

      Parameters:
        `number` - the number to test
      Returns:
        true if the number is an Integer

    - #### public static boolean isLong(Number number)

      Tests whether a number is a Long.

      Parameters:
        `number` - the number to test
      Returns:
        true if the number is a Long

    - #### public static boolean isShort(Number number)

      Tests whether a number is a Short.

      Parameters:
        `number` - the number to test
      Returns:
        true if the number is a Short

    - #### public static Number leftShift(Number left, Number right)

      Left shift operation on integral numbers.

      The shift distance (right operand) must be an integral type. The value to shift (left operand) must also be integral.

      throws:
        UnsupportedOperationException if shift distance is floating-point or BigDecimal
      Parameters:
        `left` - the value to shift (must be integral)
        `right` - the shift distance (must be integral)
      Returns:
        the left-shifted value

    - #### protected Number leftShiftImpl(Number left, Number right)

      Left shift of a number.

      Default implementation throws UnsupportedOperationException. Subclasses supporting bit shifting must override.

      throws:
        UnsupportedOperationException if not supported for this type
      Parameters:
        `left` - the value to shift
        `right` - the shift distance
      Returns:
        the left-shifted value

    - #### public static Number mod(Number left, Number right)

      Modulo operation on two numbers (for backwards compatibility).

      This method is retained for backwards compatibility

      Parameters:
        `left` - the dividend
        `right` - the divisor
      Returns:
        the modulo result

    - #### protected Number modImpl(Number left, Number right)

      Modulo of two numbers.

      Default implementation throws UnsupportedOperationException. Subclasses supporting modulo must override.

      throws:
        UnsupportedOperationException if not supported for this type
      Parameters:
        `left` - the dividend
        `right` - the divisor
      Returns:
        the modulo result

    - #### public static Number multiply(Number left, Number right)

      Multiplies two numbers using type promotion rules.

      Parameters:
        `left` - the first multiplicand
        `right` - the second multiplicand
      Returns:
        the product using the appropriate NumberMath instance

    - #### public abstract Number multiplyImpl(Number left, Number right)

      Multiplies two numbers.

      Subclasses must implement this method according to type promotion hierarchy rules.

      Parameters:
        `left` - the first multiplicand
        `right` - the second multiplicand
      Returns:
        the product

    - #### public static Number or(Number left, Number right)

      Bitwise OR operation on two integral numbers.

      throws:
        UnsupportedOperationException if operands are not integral types
      Parameters:
        `left` - the first operand
        `right` - the second operand
      Returns:
        the bitwise OR result

    - #### protected Number orImpl(Number left, Number right)

      Bitwise OR of two numbers.

      Default implementation throws UnsupportedOperationException. Subclasses supporting bitwise operations must override.

      throws:
        UnsupportedOperationException if not supported for this type
      Parameters:
        `left` - the first operand
        `right` - the second operand
      Returns:
        the bitwise OR result

    - #### public static Number remainder(Number left, Number right)

      Remainder operation on two numbers.

      Returns the remainder after integer division.

      throws:
        UnsupportedOperationException if operands don't support remainder operation
      Parameters:
        `left` - the dividend
        `right` - the divisor
      Returns:
        the remainder

    - #### protected Number remainderImpl(Number left, Number right)

      Remainder of two numbers.

      Default implementation throws UnsupportedOperationException. Subclasses supporting remainder must override.

      throws:
        UnsupportedOperationException if not supported for this type
      Parameters:
        `left` - the dividend
        `right` - the divisor
      Returns:
        the remainder

    - #### public static Number rightShift(Number left, Number right)

      Right shift operation on integral numbers.

      The shift distance (right operand) must be an integral type. The value to shift (left operand) must also be integral.

      throws:
        UnsupportedOperationException if shift distance is floating-point or BigDecimal
      Parameters:
        `left` - the value to shift (must be integral)
        `right` - the shift distance (must be integral)
      Returns:
        the right-shifted value

    - #### protected Number rightShiftImpl(Number left, Number right)

      Right shift of a number.

      Default implementation throws UnsupportedOperationException. Subclasses supporting bit shifting must override.

      throws:
        UnsupportedOperationException if not supported for this type
      Parameters:
        `left` - the value to shift
        `right` - the shift distance
      Returns:
        the right-shifted value

    - #### public static Number rightShiftUnsigned(Number left, Number right)

      Unsigned right shift operation on integral numbers.

      The shift distance (right operand) must be an integral type. The value to shift (left operand) must also be integral.

      throws:
        UnsupportedOperationException if shift distance is floating-point or BigDecimal
      Parameters:
        `left` - the value to shift (must be integral)
        `right` - the shift distance (must be integral)
      Returns:
        the unsigned right-shifted value

    - #### protected Number rightShiftUnsignedImpl(Number left, Number right)

      Unsigned right shift of a number.

      Default implementation throws UnsupportedOperationException. Subclasses supporting bit shifting must override.

      throws:
        UnsupportedOperationException if not supported for this type
      Parameters:
        `left` - the value to shift
        `right` - the shift distance
      Returns:
        the unsigned right-shifted value

    - #### public static Number subtract(Number left, Number right)

      Subtracts two numbers using type promotion rules.

      Parameters:
        `left` - the minuend
        `right` - the subtrahend
      Returns:
        the difference using the appropriate NumberMath instance

    - #### public abstract Number subtractImpl(Number left, Number right)

      Subtracts two numbers.

      Subclasses must implement this method according to type promotion hierarchy rules.

      Parameters:
        `left` - the minuend
        `right` - the subtrahend
      Returns:
        the difference

    - #### public static BigDecimal toBigDecimal(Number n)

      Converts a number to a BigDecimal.

      Handles BigDecimal, BigInteger, integral types, and floating-point types. Floating-point numbers are converted via their string representation to preserve precision.

      Parameters:
        `n` - the number to convert (must not be null)
      Returns:
        a BigDecimal representation of the number

    - #### public static BigInteger toBigInteger(Number n)

      Converts a number to a BigInteger.

      Handles BigInteger, integral types, floating-point types, and BigDecimal. Floating-point numbers are first converted to BigDecimal before extraction.

      Parameters:
        `n` - the number to convert (must not be null)
      Returns:
        a BigInteger representation of the number

    - #### public static Number unaryMinus(Number left)

      Unary negation of a number.

      Parameters:
        `left` - the operand
      Returns:
        the negation

    - #### protected abstract Number unaryMinusImpl(Number left)

      Negates a number.

      Subclasses must implement this method according to type promotion hierarchy rules.

      Parameters:
        `left` - the operand
      Returns:
        the negation

    - #### public static Number unaryPlus(Number left)

      Unary plus (identity) operation on a number.

      Parameters:
        `left` - the operand
      Returns:
        the same value

    - #### protected abstract Number unaryPlusImpl(Number left)

      Returns the number as-is (unary plus/identity).

      Subclasses must implement this method according to type promotion hierarchy rules.

      Parameters:
        `left` - the operand
      Returns:
        the same value

    - #### public static Number xor(Number left, Number right)

      Bitwise XOR operation on two integral numbers.

      throws:
        UnsupportedOperationException if operands are not integral types
      Parameters:
        `left` - the first operand
        `right` - the second operand
      Returns:
        the bitwise XOR result

    - #### protected Number xorImpl(Number left, Number right)

      Bitwise XOR of two numbers.

      Default implementation throws UnsupportedOperationException. Subclasses supporting bitwise operations must override.

      throws:
        UnsupportedOperationException if not supported for this type
      Parameters:
        `left` - the first operand
        `right` - the second operand
      Returns:
        the bitwise XOR result