Revision 3019

View differences:

org.gvsig.tools/library/trunk/org.gvsig.tools/org.gvsig.tools.lib/src/main/java/org/gvsig/tools/math/BigDecimalUtils.java
1
/*
2
 * To change this license header, choose License Headers in Project Properties.
3
 * To change this template file, choose Tools | Templates
4
 * and open the template in the editor.
5
 */
6
package org.gvsig.tools.math;
7

  
8
import java.math.BigDecimal;
9
import java.math.BigInteger;
10
import java.math.MathContext;
11
import org.apache.commons.lang3.mutable.MutableInt;
12

  
13
/**
14
 *
15
 * @author fdiaz
16
 */
17
public class BigDecimalUtils {
18

  
19
    public static BigDecimal force(BigDecimal d, int s, int p) {
20
        boolean hasExpectedScale = s>=0;
21
        if (d.precision() == p && (!hasExpectedScale || d.scale() == s)) {
22
            return d;
23
        }
24
        if (hasExpectedScale && d.scale() > s) {
25
            throw new ArithmeticException("Overflow: can't force value '"
26
                    + d.toString() + "' ("
27
                    + d.precision() + "." + d.scale() + ") to ("
28
                    + p + "," + s + ")");
29
        }
30
        if(hasExpectedScale){
31
            if (d.precision() - d.scale() > p - s) {
32
                throw new ArithmeticException("Overflow: can't force value '"
33
                        + d.toString() + "' ("
34
                        + d.precision() + "." + d.scale() + ") to ("
35
                        + p + "," + s + ")");
36
            }
37
            BigInteger unscaledValue = d.unscaledValue().multiply(BigInteger.TEN.pow(s-d.scale()));
38
            BigDecimal x = new BigDecimal(
39
                    unscaledValue, 
40
                    s, 
41
                    new MathContext(p));
42
            return x;
43
        } else {
44
            if (d.precision() > p) {
45
                throw new ArithmeticException("Overflow: can't force value '"
46
                        + d.toString() + "' ("
47
                        + d.precision() + "." + d.scale() + ") to ("
48
                        + p + "," + s + ")");
49
            }
50
            return d;
51
        }
52
    }
53
      
54
    public static boolean isValid(BigDecimal d, int s, int p) {
55
        if(d == null){
56
            return true;
57
        }
58
        if (d.precision() == p && d.scale() == s) {
59
            return true;
60
        }
61
        if (d.scale() > s) {
62
            return false;
63
        }
64
        if (d.precision() - d.scale() > p - s) {
65
            return false;
66
        }
67
        return true;
68
    }
69

  
70
    public static BigDecimal fixIfCan(BigDecimal d, MutableInt s, MutableInt p) {
71
        if (d.precision() == p.intValue() && d.scale() == s.intValue()) {
72
            return d;
73
        }
74
        if (d.scale() > s.intValue()) {
75
            p.setValue( d.precision() + (d.scale() - s.intValue()) );
76
            s.setValue(d.scale());
77
            return d;
78
        }
79
        if (d.precision() - d.scale() > p.intValue() - s.intValue()) {
80
            p.setValue(Math.max(d.precision(), p.intValue()));
81
            s.setValue(d.scale());
82
            return d;
83
        }
84
        BigInteger unscaledValue = d.unscaledValue().multiply(BigInteger.TEN.pow(s.intValue()-d.scale()));
85
        BigDecimal x = new BigDecimal(
86
                unscaledValue, 
87
                s.intValue(), 
88
                new MathContext(p.intValue()));
89

  
90
        return x;
91
    }
92
      
93
    
94
}

Also available in: Unified diff