1 package org.codehaus.groovy.runtime;
2
3 import java.math.BigDecimal;
4
5 /***
6 * BigDecimal NumberMath operations
7 *
8 * @author Steve Goetze
9 */
10 public class BigDecimalMath extends NumberMath {
11
12
13
14 public static final int MAX_DIVISION_SCALE = 10;
15
16 protected static BigDecimalMath instance = new BigDecimalMath();
17
18 private BigDecimalMath() {}
19
20 protected Number absImpl(Number number) {
21 return toBigDecimal(number).abs();
22 }
23
24 protected Number addImpl(Number left, Number right) {
25 return toBigDecimal(left).add(toBigDecimal(right));
26 }
27
28 protected Number subtractImpl(Number left, Number right) {
29 return toBigDecimal(left).subtract(toBigDecimal(right));
30 }
31
32 protected Number multiplyImpl(Number left, Number right) {
33 return toBigDecimal(left).multiply(toBigDecimal(right));
34 }
35
36 protected Number divideImpl(Number left, Number right) {
37
38
39
40
41
42 BigDecimal bigLeft = toBigDecimal(left);
43 BigDecimal bigRight = toBigDecimal(right);
44 int scale = Math.max(bigLeft.scale(), bigRight.scale());
45 return normalize(bigLeft.divide(bigRight, Math.max(scale, MAX_DIVISION_SCALE), BigDecimal.ROUND_HALF_UP));
46 }
47
48 protected int compareToImpl(Number left, Number right) {
49 return toBigDecimal(left).compareTo(toBigDecimal(right));
50 }
51
52 private BigDecimal normalize(BigDecimal number) {
53
54
55 if (number.signum()==0) {
56
57 return number.setScale(0);
58 }
59
60 try {
61 while (true) {
62 number = number.setScale(number.scale()-1);
63 }
64 } catch (ArithmeticException e) {
65 return number;
66 }
67 }
68
69 protected Number negateImpl(Number left) {
70 return toBigDecimal(left).negate();
71 }
72 }