EMMA Coverage Report (generated Sun Mar 01 22:06:14 CET 2015)
[all classes][org.h2.value]

COVERAGE SUMMARY FOR SOURCE FILE [ValueDecimal.java]

nameclass, %method, %block, %line, %
ValueDecimal.java100% (1/1)100% (27/27)97%  (332/343)97%  (74.9/77)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class ValueDecimal100% (1/1)100% (27/27)97%  (332/343)97%  (74.9/77)
setScale (BigDecimal, int): BigDecimal 100% (1/1)69%  (11/16)67%  (2/3)
ValueDecimal (BigDecimal): void 100% (1/1)85%  (29/34)86%  (6/7)
checkPrecision (long): boolean 100% (1/1)93%  (14/15)96%  (2.9/3)
<static initializer> 100% (1/1)100% (11/11)100% (2/2)
add (Value): Value 100% (1/1)100% (10/10)100% (2/2)
compareSecure (Value, CompareMode): int 100% (1/1)100% (9/9)100% (2/2)
convertPrecision (long, boolean): Value 100% (1/1)100% (20/20)100% (5/5)
convertScale (boolean, int): Value 100% (1/1)100% (27/27)100% (7/7)
divide (Value): Value 100% (1/1)100% (44/44)100% (10/10)
equals (Object): boolean 100% (1/1)100% (14/14)100% (1/1)
get (BigDecimal): ValueDecimal 100% (1/1)100% (21/21)100% (5/5)
getBigDecimal (): BigDecimal 100% (1/1)100% (3/3)100% (1/1)
getDisplaySize (): int 100% (1/1)100% (6/6)100% (1/1)
getMemory (): int 100% (1/1)100% (6/6)100% (1/1)
getObject (): Object 100% (1/1)100% (3/3)100% (1/1)
getPrecision (): long 100% (1/1)100% (12/12)100% (3/3)
getSQL (): String 100% (1/1)100% (3/3)100% (1/1)
getScale (): int 100% (1/1)100% (4/4)100% (1/1)
getSignum (): int 100% (1/1)100% (4/4)100% (1/1)
getString (): String 100% (1/1)100% (23/23)100% (6/6)
getType (): int 100% (1/1)100% (2/2)100% (1/1)
hashCode (): int 100% (1/1)100% (4/4)100% (1/1)
modulus (Value): ValueDecimal 100% (1/1)100% (21/21)100% (5/5)
multiply (Value): Value 100% (1/1)100% (10/10)100% (2/2)
negate (): Value 100% (1/1)100% (5/5)100% (1/1)
set (PreparedStatement, int): void 100% (1/1)100% (6/6)100% (2/2)
subtract (Value): Value 100% (1/1)100% (10/10)100% (2/2)

1/*
2 * Copyright 2004-2014 H2 Group. Multiple-Licensed under the MPL 2.0,
3 * and the EPL 1.0 (http://h2database.com/html/license.html).
4 * Initial Developer: H2 Group
5 */
6package org.h2.value;
7 
8import java.math.BigDecimal;
9import java.sql.PreparedStatement;
10import java.sql.SQLException;
11 
12import org.h2.api.ErrorCode;
13import org.h2.message.DbException;
14import org.h2.util.MathUtils;
15 
16/**
17 * Implementation of the DECIMAL data type.
18 */
19public class ValueDecimal extends Value {
20 
21    /**
22     * The value 'zero'.
23     */
24    public static final Object ZERO = new ValueDecimal(BigDecimal.ZERO);
25 
26    /**
27     * The value 'one'.
28     */
29    public static final Object ONE = new ValueDecimal(BigDecimal.ONE);
30 
31    /**
32     * The default precision for a decimal value.
33     */
34    static final int DEFAULT_PRECISION = 65535;
35 
36    /**
37     * The default scale for a decimal value.
38     */
39    static final int DEFAULT_SCALE = 32767;
40 
41    /**
42     * The default display size for a decimal value.
43     */
44    static final int DEFAULT_DISPLAY_SIZE = 65535;
45 
46    private static final int DIVIDE_SCALE_ADD = 25;
47 
48    /**
49     * The maximum scale of a BigDecimal value.
50     */
51    private static final int BIG_DECIMAL_SCALE_MAX = 100000;
52 
53    private final BigDecimal value;
54    private String valueString;
55    private int precision;
56 
57    private ValueDecimal(BigDecimal value) {
58        if (value == null) {
59            throw new IllegalArgumentException("null");
60        } else if (!value.getClass().equals(BigDecimal.class)) {
61            throw DbException.get(ErrorCode.INVALID_CLASS_2,
62                    BigDecimal.class.getName(), value.getClass().getName());
63        }
64        this.value = value;
65    }
66 
67    @Override
68    public Value add(Value v) {
69        ValueDecimal dec = (ValueDecimal) v;
70        return ValueDecimal.get(value.add(dec.value));
71    }
72 
73    @Override
74    public Value subtract(Value v) {
75        ValueDecimal dec = (ValueDecimal) v;
76        return ValueDecimal.get(value.subtract(dec.value));
77    }
78 
79    @Override
80    public Value negate() {
81        return ValueDecimal.get(value.negate());
82    }
83 
84    @Override
85    public Value multiply(Value v) {
86        ValueDecimal dec = (ValueDecimal) v;
87        return ValueDecimal.get(value.multiply(dec.value));
88    }
89 
90    @Override
91    public Value divide(Value v) {
92        ValueDecimal dec = (ValueDecimal) v;
93        if (dec.value.signum() == 0) {
94            throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL());
95        }
96        BigDecimal bd = value.divide(dec.value,
97                value.scale() + DIVIDE_SCALE_ADD,
98                BigDecimal.ROUND_HALF_DOWN);
99        if (bd.signum() == 0) {
100            bd = BigDecimal.ZERO;
101        } else if (bd.scale() > 0) {
102            if (!bd.unscaledValue().testBit(0)) {
103                bd = bd.stripTrailingZeros();
104            }
105        }
106        return ValueDecimal.get(bd);
107    }
108 
109    @Override
110    public ValueDecimal modulus(Value v) {
111        ValueDecimal dec = (ValueDecimal) v;
112        if (dec.value.signum() == 0) {
113            throw DbException.get(ErrorCode.DIVISION_BY_ZERO_1, getSQL());
114        }
115        BigDecimal bd = value.remainder(dec.value);
116        return ValueDecimal.get(bd);
117    }
118 
119    @Override
120    public String getSQL() {
121        return getString();
122    }
123 
124    @Override
125    public int getType() {
126        return Value.DECIMAL;
127    }
128 
129    @Override
130    protected int compareSecure(Value o, CompareMode mode) {
131        ValueDecimal v = (ValueDecimal) o;
132        return value.compareTo(v.value);
133    }
134 
135    @Override
136    public int getSignum() {
137        return value.signum();
138    }
139 
140    @Override
141    public BigDecimal getBigDecimal() {
142        return value;
143    }
144 
145    @Override
146    public String getString() {
147        if (valueString == null) {
148            String p = value.toPlainString();
149            if (p.length() < 40) {
150                valueString = p;
151            } else {
152                valueString = value.toString();
153            }
154        }
155        return valueString;
156    }
157 
158    @Override
159    public long getPrecision() {
160        if (precision == 0) {
161            precision = value.precision();
162        }
163        return precision;
164    }
165 
166    @Override
167    public boolean checkPrecision(long prec) {
168        if (prec == DEFAULT_PRECISION) {
169            return true;
170        }
171        return getPrecision() <= prec;
172    }
173 
174    @Override
175    public int getScale() {
176        return value.scale();
177    }
178 
179    @Override
180    public int hashCode() {
181        return value.hashCode();
182    }
183 
184    @Override
185    public Object getObject() {
186        return value;
187    }
188 
189    @Override
190    public void set(PreparedStatement prep, int parameterIndex)
191            throws SQLException {
192        prep.setBigDecimal(parameterIndex, value);
193    }
194 
195    @Override
196    public Value convertScale(boolean onlyToSmallerScale, int targetScale) {
197        if (value.scale() == targetScale) {
198            return this;
199        }
200        if (onlyToSmallerScale || targetScale >= DEFAULT_SCALE) {
201            if (value.scale() < targetScale) {
202                return this;
203            }
204        }
205        BigDecimal bd = ValueDecimal.setScale(value, targetScale);
206        return ValueDecimal.get(bd);
207    }
208 
209    @Override
210    public Value convertPrecision(long precision, boolean force) {
211        if (getPrecision() <= precision) {
212            return this;
213        }
214        if (force) {
215            return get(BigDecimal.valueOf(value.doubleValue()));
216        }
217        throw DbException.get(
218                ErrorCode.NUMERIC_VALUE_OUT_OF_RANGE_1,
219                Long.toString(precision));
220    }
221 
222    /**
223     * Get or create big decimal value for the given big decimal.
224     *
225     * @param dec the bit decimal
226     * @return the value
227     */
228    public static ValueDecimal get(BigDecimal dec) {
229        if (BigDecimal.ZERO.equals(dec)) {
230            return (ValueDecimal) ZERO;
231        } else if (BigDecimal.ONE.equals(dec)) {
232            return (ValueDecimal) ONE;
233        }
234        return (ValueDecimal) Value.cache(new ValueDecimal(dec));
235    }
236 
237    @Override
238    public int getDisplaySize() {
239        // add 2 characters for '-' and '.'
240        return MathUtils.convertLongToInt(getPrecision() + 2);
241    }
242 
243    @Override
244    public boolean equals(Object other) {
245        // Two BigDecimal objects are considered equal only if they are equal in
246        // value and scale (thus 2.0 is not equal to 2.00 when using equals;
247        // however -0.0 and 0.0 are). Can not use compareTo because 2.0 and 2.00
248        // have different hash codes
249        return other instanceof ValueDecimal &&
250                value.equals(((ValueDecimal) other).value);
251    }
252 
253    @Override
254    public int getMemory() {
255        return value.precision() + 120;
256    }
257 
258    /**
259     * Set the scale of a BigDecimal value.
260     *
261     * @param bd the BigDecimal value
262     * @param scale the new scale
263     * @return the scaled value
264     */
265    public static BigDecimal setScale(BigDecimal bd, int scale) {
266        if (scale > BIG_DECIMAL_SCALE_MAX || scale < -BIG_DECIMAL_SCALE_MAX) {
267            throw DbException.getInvalidValueException("scale", scale);
268        }
269        return bd.setScale(scale, BigDecimal.ROUND_HALF_UP);
270    }
271 
272}

[all classes][org.h2.value]
EMMA 2.0.5312 (C) Vladimir Roubtsov