code: public static NumberMath getMath(Number left, Number right) {
          // FloatingPointMath wins according to promotion Matrix
          if (isFloatingPoint(left) || isFloatingPoint(right)) {
              return FloatingPointMath.INSTANCE;
          }
          NumberMath leftMath = getMath(left);
          NumberMath rightMath = getMath(right);
  
          if (leftMath == BigDecimalMath.INSTANCE || rightMath == BigDecimalMath.INSTANCE) {
              return BigDecimalMath.INSTANCE;
          }
          if (leftMath == BigIntegerMath.INSTANCE || rightMath == BigIntegerMath.INSTANCE) {
              return BigIntegerMath.INSTANCE;
          }
          if (leftMath == LongMath.INSTANCE || rightMath == LongMath.INSTANCE) {
              return LongMath.INSTANCE;
          }
          if (leftMath == IntegerMath.INSTANCE || rightMath == IntegerMath.INSTANCE) {
              return IntegerMath.INSTANCE;
          }
          // also for custom Number implementations
          return BigDecimalMath.INSTANCE;
      }
docs: 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