Class NumberMath

  • Direct Known Subclasses:
    BigDecimalMath, BigIntegerMath, FloatingPointMath, IntegerMath, LongMath

    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).
    • Constructor Detail

      • NumberMath

        public NumberMath()
    • Method Detail

      • compareTo

        public static int compareTo​(Number left,
                                    Number right)
      • leftShift

        public static Number leftShift​(Number left,
                                       Number right)
        For this operation, consider the operands independently. Throw an exception if the right operand (shift distance) is not an integral type. For the left operand (shift value) also require an integral type, but do NOT promote from Integer to Long. This is consistent with Java, and makes sense for the shift operators.
      • rightShift

        public static Number rightShift​(Number left,
                                        Number right)
        For this operation, consider the operands independently. Throw an exception if the right operand (shift distance) is not an integral type. For the left operand (shift value) also require an integral type, but do NOT promote from Integer to Long. This is consistent with Java, and makes sense for the shift operators.
      • rightShiftUnsigned

        public static Number rightShiftUnsigned​(Number left,
                                                Number right)
        For this operation, consider the operands independently. Throw an exception if the right operand (shift distance) is not an integral type. For the left operand (shift value) also require an integral type, but do NOT promote from Integer to Long. This is consistent with Java, and makes sense for the shift operators.
      • bitwiseNegate

        public static Number bitwiseNegate​(Number left)
      • unaryMinus

        public static Number unaryMinus​(Number left)
      • unaryPlus

        public static Number unaryPlus​(Number left)
      • isFloatingPoint

        public static boolean isFloatingPoint​(Number number)
      • isInteger

        public static boolean isInteger​(Number number)
      • isShort

        public static boolean isShort​(Number number)
      • isByte

        public static boolean isByte​(Number number)
      • isLong

        public static boolean isLong​(Number number)
      • isBigDecimal

        public static boolean isBigDecimal​(Number number)
      • isBigInteger

        public static boolean isBigInteger​(Number number)
      • getMath

        public static NumberMath getMath​(Number left,
                                         Number right)
        Determine which NumberMath instance to use, given the supplied operands. This method implements the type promotion rules discussed in the documentation. Note that by the time this method is called, any Byte, Character or Short operands will have been promoted to Integer. For reference, here is the 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 Note that for division, if either operand isFloatingPoint, the result will be floating. Otherwise, the result is BigDecimal
      • absImpl

        protected abstract Number absImpl​(Number number)
      • compareToImpl

        public abstract int compareToImpl​(Number left,
                                          Number right)
      • unaryMinusImpl

        protected abstract Number unaryMinusImpl​(Number left)
      • unaryPlusImpl

        protected abstract Number unaryPlusImpl​(Number left)
      • bitwiseNegateImpl

        protected Number bitwiseNegateImpl​(Number left)
      • rightShiftUnsignedImpl

        protected Number rightShiftUnsignedImpl​(Number left,
                                                Number right)