~ubuntu-branches/ubuntu/lucid/groovy/lucid

« back to all changes in this revision

Viewing changes to src/main/org/codehaus/groovy/runtime/typehandling/BigDecimalMath.java

  • Committer: Bazaar Package Importer
  • Author(s): Torsten Werner
  • Date: 2009-05-19 21:49:37 UTC
  • mfrom: (3.2.4 squeeze)
  • Revision ID: james.westby@ubuntu.com-20090519214937-56mctwb05t3xd63r
Tags: 1.6.3-1
New upstream release

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
 
/*
2
 
 * Copyright 2003-2007 the original author or authors.
3
 
 *
4
 
 * Licensed under the Apache License, Version 2.0 (the "License");
5
 
 * you may not use this file except in compliance with the License.
6
 
 * You may obtain a copy of the License at
7
 
 *
8
 
 *     http://www.apache.org/licenses/LICENSE-2.0
9
 
 *
10
 
 * Unless required by applicable law or agreed to in writing, software
11
 
 * distributed under the License is distributed on an "AS IS" BASIS,
12
 
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13
 
 * See the License for the specific language governing permissions and
14
 
 * limitations under the License.
15
 
 */
16
 
 
17
 
package org.codehaus.groovy.runtime.typehandling;
18
 
 
19
 
import java.math.BigDecimal;
20
 
 
21
 
/**
22
 
 * BigDecimal NumberMath operations
23
 
 * 
24
 
 * @author Steve Goetze
25
 
 */
26
 
public class BigDecimalMath extends NumberMath {
27
 
 
28
 
        //This is an arbitrary value, picked as a reasonable choice for a rounding point
29
 
        //for typical user math.
30
 
        public static final int MAX_DIVISION_SCALE = 10;
31
 
        
32
 
        public static final BigDecimalMath INSTANCE = new BigDecimalMath();
33
 
        
34
 
        private BigDecimalMath() {}
35
 
 
36
 
        protected Number absImpl(Number number) {
37
 
                return toBigDecimal(number).abs();
38
 
        }
39
 
        
40
 
        public Number addImpl(Number left, Number right) {
41
 
                return toBigDecimal(left).add(toBigDecimal(right));
42
 
        }
43
 
 
44
 
        public Number subtractImpl(Number left, Number right) {
45
 
                return toBigDecimal(left).subtract(toBigDecimal(right));
46
 
        }
47
 
 
48
 
        public Number multiplyImpl(Number left, Number right) {
49
 
                return toBigDecimal(left).multiply(toBigDecimal(right));
50
 
        }
51
 
 
52
 
        public Number divideImpl(Number left, Number right) {
53
 
                //Hack until Java 1.5 BigDecimal is available.  For now, pick
54
 
                //a result scale which is the maximum of the scale of the
55
 
                //two operands and an arbitrary maximum (similar to what a
56
 
                //handheld calculator would do).  Then, normalize the result
57
 
                //by removing any trailing zeros.
58
 
                BigDecimal bigLeft = toBigDecimal(left);
59
 
                BigDecimal bigRight = toBigDecimal(right);
60
 
                int scale = Math.max(bigLeft.scale(), bigRight.scale());
61
 
                return normalize(bigLeft.divide(bigRight, Math.max(scale, MAX_DIVISION_SCALE), BigDecimal.ROUND_HALF_UP));
62
 
        }
63
 
        
64
 
        public int compareToImpl(Number left, Number right) {
65
 
                return toBigDecimal(left).compareTo(toBigDecimal(right));
66
 
        }
67
 
        
68
 
        private BigDecimal normalize(BigDecimal number) {
69
 
        // we have to take care of the case number==0, because 0 can have every
70
 
        // scale and the test in the while loop would never end
71
 
        if (number.signum()==0) {
72
 
            // the smallest scale for 0 is 0
73
 
            return number.setScale(0);
74
 
        }
75
 
        // rescale until we found the smallest possible scale
76
 
                try {
77
 
                        while (true) {
78
 
                                number = number.setScale(number.scale()-1);
79
 
                        } 
80
 
                } catch (ArithmeticException e) {
81
 
                        return number;
82
 
                }
83
 
        }
84
 
 
85
 
    protected Number unaryMinusImpl(Number left) {
86
 
        return toBigDecimal(left).negate();
87
 
    }
88
 
}
 
1
/*
 
2
 * Copyright 2003-2007 the original author or authors.
 
3
 *
 
4
 * Licensed under the Apache License, Version 2.0 (the "License");
 
5
 * you may not use this file except in compliance with the License.
 
6
 * You may obtain a copy of the License at
 
7
 *
 
8
 *     http://www.apache.org/licenses/LICENSE-2.0
 
9
 *
 
10
 * Unless required by applicable law or agreed to in writing, software
 
11
 * distributed under the License is distributed on an "AS IS" BASIS,
 
12
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 
13
 * See the License for the specific language governing permissions and
 
14
 * limitations under the License.
 
15
 */
 
16
 
 
17
package org.codehaus.groovy.runtime.typehandling;
 
18
 
 
19
import java.math.BigDecimal;
 
20
 
 
21
/**
 
22
 * BigDecimal NumberMath operations
 
23
 * 
 
24
 * @author Steve Goetze
 
25
 */
 
26
public class BigDecimalMath extends NumberMath {
 
27
 
 
28
        //This is an arbitrary value, picked as a reasonable choice for a rounding point
 
29
        //for typical user math.
 
30
        public static final int MAX_DIVISION_SCALE = 10;
 
31
        
 
32
        public static final BigDecimalMath INSTANCE = new BigDecimalMath();
 
33
        
 
34
        private BigDecimalMath() {}
 
35
 
 
36
        protected Number absImpl(Number number) {
 
37
                return toBigDecimal(number).abs();
 
38
        }
 
39
        
 
40
        public Number addImpl(Number left, Number right) {
 
41
                return toBigDecimal(left).add(toBigDecimal(right));
 
42
        }
 
43
 
 
44
        public Number subtractImpl(Number left, Number right) {
 
45
                return toBigDecimal(left).subtract(toBigDecimal(right));
 
46
        }
 
47
 
 
48
        public Number multiplyImpl(Number left, Number right) {
 
49
                return toBigDecimal(left).multiply(toBigDecimal(right));
 
50
        }
 
51
 
 
52
        public Number divideImpl(Number left, Number right) {
 
53
                //Hack until Java 1.5 BigDecimal is available.  For now, pick
 
54
                //a result scale which is the maximum of the scale of the
 
55
                //two operands and an arbitrary maximum (similar to what a
 
56
                //handheld calculator would do).  Then, normalize the result
 
57
                //by removing any trailing zeros.
 
58
                BigDecimal bigLeft = toBigDecimal(left);
 
59
                BigDecimal bigRight = toBigDecimal(right);
 
60
                int scale = Math.max(bigLeft.scale(), bigRight.scale());
 
61
                return normalize(bigLeft.divide(bigRight, Math.max(scale, MAX_DIVISION_SCALE), BigDecimal.ROUND_HALF_UP));
 
62
        }
 
63
        
 
64
        public int compareToImpl(Number left, Number right) {
 
65
                return toBigDecimal(left).compareTo(toBigDecimal(right));
 
66
        }
 
67
        
 
68
        private BigDecimal normalize(BigDecimal number) {
 
69
        // we have to take care of the case number==0, because 0 can have every
 
70
        // scale and the test in the while loop would never end
 
71
        if (number.signum()==0) {
 
72
            // the smallest scale for 0 is 0
 
73
            return number.setScale(0);
 
74
        }
 
75
        // rescale until we found the smallest possible scale
 
76
                try {
 
77
                        while (true) {
 
78
                                number = number.setScale(number.scale()-1);
 
79
                        } 
 
80
                } catch (ArithmeticException e) {
 
81
                        return number;
 
82
                }
 
83
        }
 
84
 
 
85
    protected Number unaryMinusImpl(Number left) {
 
86
        return toBigDecimal(left).negate();
 
87
    }
 
88
}