1 5 package org.codehaus.groovy.runtime; 6 7 import java.math.BigDecimal ; 8 import java.math.BigInteger ; 9 10 34 public abstract class NumberMath extends Object { 35 36 public static Number abs(Number number) { 37 return getMath(number).absImpl(number); 38 } 39 40 public static Number add(Number left, Number right) { 41 return getMath(left, right).addImpl(left,right); 42 } 43 44 public static Number subtract(Number left, Number right) { 45 return getMath(left,right).subtractImpl(left,right); 46 } 47 48 public static Number multiply(Number left, Number right) { 49 return getMath(left,right).multiplyImpl(left,right); 50 } 51 52 public static Number divide(Number left, Number right) { 53 return getMath(left,right).divideImpl(left,right); 54 } 55 56 public static int compareTo(Number left, Number right) { 57 return getMath(left,right).compareToImpl(left, right); 58 } 59 60 public static Number or(Number left, Number right) { 61 return getMath(left,right).orImpl(left, right); 62 } 63 64 public static Number and(Number left, Number right) { 65 return getMath(left,right).andImpl(left, right); 66 } 67 68 public static Number intdiv(Number left, Number right) { 69 return getMath(left,right).intdivImpl(left,right); 70 } 71 72 public static Number mod(Number left, Number right) { 73 return getMath(left,right).modImpl(left, right); 74 } 75 76 82 public static Number leftShift(Number left, Number right) { 83 if (isFloatingPoint(right) || isBigDecimal(right)) { 84 throw new UnsupportedOperationException ("Shift distance must be an integral type, but " + right + " (" + right.getClass().getName() + ") was supplied"); 85 } 86 return getMath(left).leftShiftImpl(left,right); 87 } 88 89 95 public static Number rightShift(Number left, Number right) { 96 if (isFloatingPoint(right) || isBigDecimal(right)) { 97 throw new UnsupportedOperationException ("Shift distance must be an integral type, but " + right + " (" + right.getClass().getName() + ") was supplied"); 98 } 99 return getMath(left).rightShiftImpl(left,right); 100 } 101 102 108 public static Number rightShiftUnsigned(Number left, Number right) { 109 if (isFloatingPoint(right) || isBigDecimal(right)) { 110 throw new UnsupportedOperationException ("Shift distance must be an integral type, but " + right + " (" + right.getClass().getName() + ") was supplied"); 111 } 112 return getMath(left).rightShiftUnsignedImpl(left,right); 113 } 114 115 public static Number negate(Number left) { 116 return getMath(left).negateImpl(left); 117 } 118 119 public static boolean isFloatingPoint(Number number) { 120 return number instanceof Double || number instanceof Float ; 121 } 122 123 public static boolean isInteger(Number number) { 124 return number instanceof Integer ; 125 } 126 127 public static boolean isLong(Number number) { 128 return number instanceof Long ; 129 } 130 131 public static boolean isBigDecimal(Number number) { 132 return number instanceof BigDecimal ; 133 } 134 135 public static boolean isBigInteger(Number number) { 136 return number instanceof BigInteger ; 137 } 138 139 public static BigDecimal toBigDecimal(Number n) { 140 return (n instanceof BigDecimal ? (BigDecimal ) n : new BigDecimal (n.toString())); 141 } 142 143 public static BigInteger toBigInteger(Number n) { 144 return (n instanceof BigInteger ? (BigInteger ) n : new BigInteger (n.toString())); 145 } 146 147 163 private static NumberMath getMath(Number left, Number right) { 164 if (isFloatingPoint(left) || isFloatingPoint(right)) { 165 return FloatingPointMath.instance; 166 } 167 else if (isBigDecimal(left) || isBigDecimal(right)) { 168 return BigDecimalMath.instance; 169 } 170 else if (isBigInteger(left) || isBigInteger(right)) { 171 return BigIntegerMath.instance; 172 } 173 else if (isLong(left) || isLong(right)){ 174 return LongMath.instance; 175 } 176 return IntegerMath.instance; 177 } 178 179 private static NumberMath getMath(Number number) { 180 if (isInteger(number)) { 181 return IntegerMath.instance; 182 } 183 else if (isLong(number)) { 184 return LongMath.instance; 185 } 186 else if (isFloatingPoint(number)) { 187 return FloatingPointMath.instance; 188 } 189 else if (isBigDecimal(number)) { 190 return BigDecimalMath.instance; 191 } 192 else if (isBigInteger(number)) { 193 return BigIntegerMath.instance; 194 } 195 else { 196 throw new IllegalArgumentException ("An unexpected Number subclass was supplied."); 197 } 198 } 199 200 protected abstract Number absImpl(Number number); 202 protected abstract Number addImpl(Number left, Number right); 203 protected abstract Number subtractImpl(Number left, Number right); 204 protected abstract Number multiplyImpl(Number left, Number right); 205 protected abstract Number divideImpl(Number left, Number right); 206 protected abstract int compareToImpl(Number left, Number right); 207 protected abstract Number negateImpl(Number left); 208 209 210 protected Number andImpl(Number left, Number right) { 211 throw createUnsupportedException("and()", left); 212 } 213 214 protected Number modImpl(Number left, Number right) { 215 throw createUnsupportedException("mod()", left); 216 } 217 218 protected Number intdivImpl(Number left, Number right) { 219 throw createUnsupportedException("intdiv()", left); 220 } 221 222 protected Number orImpl(Number left, Number right) { 223 throw createUnsupportedException("or()", left); 224 } 225 226 protected Number leftShiftImpl(Number left, Number right) { 227 throw createUnsupportedException("leftShift()", left); 228 } 229 230 protected Number rightShiftImpl(Number left, Number right) { 231 throw createUnsupportedException("rightShift()", left); 232 } 233 234 protected Number rightShiftUnsignedImpl(Number left, Number right) { 235 throw createUnsupportedException("rightShiftUnsigned()", left); 236 } 237 238 protected UnsupportedOperationException createUnsupportedException(String operation, Number left) { 239 return new UnsupportedOperationException ("Cannot use " + operation + " on this number type: " + left.getClass().getName() + " with value: " + left); 240 } 241 } 242 | Popular Tags |