View Javadoc

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  	//This is an arbitrary value, picked as a reasonable choice for a rounding point
13  	//for typical user math.
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  		//Hack until Java 1.5 BigDecimal is available.  For now, pick
38  		//a result scale which is the maximum of the scale of the
39  		//two operands and an arbitrary maximum (similar to what a
40  		//handheld calculator would do).  Then, normalize the result
41  		//by removing any trailing zeros.
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  		try {
54  			while (true) {
55  				number = number.setScale(number.scale()-1);
56  			} 
57  		} catch (ArithmeticException e) {
58  			return number;
59  		}
60  	}
61  
62      protected Number negateImpl(Number left) {
63          return toBigDecimal(left).negate();
64      }
65  }