1/*
2 *  Licensed to the Apache Software Foundation (ASF) under one or more
3 *  contributor license agreements.  See the NOTICE file distributed with
4 *  this work for additional information regarding copyright ownership.
5 *  The ASF licenses this file to You under the Apache License, Version 2.0
6 *  (the "License"); you may not use this file except in compliance with
7 *  the License.  You may obtain a copy of the License at
8 *
9 *     http://www.apache.org/licenses/LICENSE-2.0
10 *
11 *  Unless required by applicable law or agreed to in writing, software
12 *  distributed under the License is distributed on an "AS IS" BASIS,
13 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 *  See the License for the specific language governing permissions and
15 *  limitations under the License.
16 */
17/**
18 * @author Elena Semukhina
19 */
20
21package org.apache.harmony.tests.java.math;
22
23import junit.framework.TestCase;
24import java.math.*;
25
26/**
27 * Class:  java.math.BigDecimal
28 * Methods: movePointLeft, movePointRight, scale, setScale, unscaledValue *
29 */
30public class BigDecimalScaleOperationsTest extends TestCase {
31    /**
32     * Check the default scale
33     */
34    public void testScaleDefault() {
35        String a = "1231212478987482988429808779810457634781384756794987";
36        int cScale = 0;
37        BigDecimal aNumber = new BigDecimal(new BigInteger(a));
38        assertTrue("incorrect scale", aNumber.scale() == cScale);
39    }
40
41    /**
42     * Check a negative scale
43     */
44    public void testScaleNeg() {
45        String a = "1231212478987482988429808779810457634781384756794987";
46        int aScale = -10;
47        int cScale = -10;
48        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
49        assertTrue("incorrect scale", aNumber.scale() == cScale);
50    }
51
52    /**
53     * Check a positive scale
54     */
55    public void testScalePos() {
56        String a = "1231212478987482988429808779810457634781384756794987";
57        int aScale = 10;
58        int cScale = 10;
59        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
60        assertTrue("incorrect scale", aNumber.scale() == cScale);
61    }
62
63    /**
64     * Check the zero scale
65     */
66    public void testScaleZero() {
67        String a = "1231212478987482988429808779810457634781384756794987";
68        int aScale = 0;
69        int cScale = 0;
70        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
71        assertTrue("incorrect scale", aNumber.scale() == cScale);
72    }
73
74    /**
75     * Check the unscaled value
76     */
77    public void testUnscaledValue() {
78        String a = "1231212478987482988429808779810457634781384756794987";
79        int aScale = 100;
80        BigInteger bNumber = new BigInteger(a);
81        BigDecimal aNumber = new BigDecimal(bNumber, aScale);
82        assertTrue("incorrect unscaled value", aNumber.unscaledValue().equals(bNumber));
83    }
84
85    /**
86     * Set a greater new scale
87     */
88    public void testSetScaleGreater() {
89        String a = "1231212478987482988429808779810457634781384756794987";
90        int aScale = 18;
91        int newScale = 28;
92        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
93        BigDecimal bNumber = aNumber.setScale(newScale);
94        assertTrue("incorrect scale", bNumber.scale() == newScale);
95        assertEquals("incorrect value", 0, bNumber.compareTo(aNumber));
96    }
97
98    /**
99     * Set a less new scale; this.scale == 8; newScale == 5.
100     */
101    public void testSetScaleLess() {
102        String a = "2.345726458768760000E+10";
103        int newScale = 5;
104        BigDecimal aNumber = new BigDecimal(a);
105        BigDecimal bNumber = aNumber.setScale(newScale);
106        assertTrue("incorrect scale", bNumber.scale() == newScale);
107        assertEquals("incorrect value", 0, bNumber.compareTo(aNumber));
108    }
109
110    /**
111     * Verify an exception when setting a new scale
112     */
113    public void testSetScaleException() {
114        String a = "1231212478987482988429808779810457634781384756794987";
115        int aScale = 28;
116        int newScale = 18;
117        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
118        try {
119            aNumber.setScale(newScale);
120            fail("ArithmeticException has not been caught");
121        } catch (ArithmeticException e) {
122            assertEquals("Improper exception message", "Rounding necessary", e.getMessage());
123        }
124    }
125
126    /**
127     * Set the same new scale
128     */
129    public void testSetScaleSame() {
130        String a = "1231212478987482988429808779810457634781384756794987";
131        int aScale = 18;
132        int newScale = 18;
133        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
134        BigDecimal bNumber = aNumber.setScale(newScale);
135        assertTrue("incorrect scale", bNumber.scale() == newScale);
136        assertTrue("incorrect value", bNumber.equals(aNumber));
137    }
138
139    /**
140     * Set a new scale
141     */
142    public void testSetScaleRoundUp() {
143        String a = "1231212478987482988429808779810457634781384756794987";
144        String b = "123121247898748298842980877981045763478139";
145        int aScale = 28;
146        int newScale = 18;
147        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
148        BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_UP);
149        assertTrue("incorrect scale", bNumber.scale() == newScale);
150        assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
151    }
152
153    /**
154     * Set a new scale
155     */
156    public void testSetScaleRoundDown() {
157        String a = "1231212478987482988429808779810457634781384756794987";
158        String b = "123121247898748298842980877981045763478138";
159        int aScale = 28;
160        int newScale = 18;
161        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
162        BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_DOWN);
163        assertTrue("incorrect scale", bNumber.scale() == newScale);
164        assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
165    }
166
167    /**
168     * Set a new scale
169     */
170    public void testSetScaleRoundCeiling() {
171        String a = "1231212478987482988429808779810457634781384756794987";
172        String b = "123121247898748298842980877981045763478139";
173        int aScale = 28;
174        int newScale = 18;
175        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
176        BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_CEILING);
177        assertTrue("incorrect scale", bNumber.scale() == newScale);
178        assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
179    }
180
181    /**
182     * Set a new scale
183     */
184    public void testSetScaleRoundFloor() {
185        String a = "1231212478987482988429808779810457634781384756794987";
186        String b = "123121247898748298842980877981045763478138";
187        int aScale = 28;
188        int newScale = 18;
189        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
190        BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_FLOOR);
191        assertTrue("incorrect scale", bNumber.scale() == newScale);
192        assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
193    }
194
195    /**
196     * Set a new scale
197     */
198    public void testSetScaleRoundHalfUp() {
199        String a = "1231212478987482988429808779810457634781384756794987";
200        String b = "123121247898748298842980877981045763478138";
201        int aScale = 28;
202        int newScale = 18;
203        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
204        BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_HALF_UP);
205        assertTrue("incorrect scale", bNumber.scale() == newScale);
206        assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
207    }
208
209    /**
210     * Set a new scale
211     */
212    public void testSetScaleRoundHalfDown() {
213        String a = "1231212478987482988429808779810457634781384756794987";
214        String b = "123121247898748298842980877981045763478138";
215        int aScale = 28;
216        int newScale = 18;
217        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
218        BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_HALF_DOWN);
219        assertTrue("incorrect scale", bNumber.scale() == newScale);
220        assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
221    }
222
223    /**
224     * Set a new scale
225     */
226    public void testSetScaleRoundHalfEven() {
227        String a = "1231212478987482988429808779810457634781384756794987";
228        String b = "123121247898748298842980877981045763478138";
229        int aScale = 28;
230        int newScale = 18;
231        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
232        BigDecimal bNumber = aNumber.setScale(newScale, BigDecimal.ROUND_HALF_EVEN);
233        assertTrue("incorrect scale", bNumber.scale() == newScale);
234        assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
235    }
236
237    /**
238     * SetScale(int, RoundingMode)
239     */
240    public void testSetScaleIntRoundingMode() {
241        String a = "1231212478987482988429808779810457634781384756794987";
242        int aScale = 28;
243        int newScale = 18;
244        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
245        BigDecimal result = aNumber.setScale(newScale, RoundingMode.HALF_EVEN);
246        String res = "123121247898748298842980.877981045763478138";
247        int resScale = 18;
248        assertEquals("incorrect value", res, result.toString());
249        assertEquals("incorrect scale", resScale, result.scale());
250    }
251
252    /**
253     * Move the decimal point to the left; the shift value is positive
254     */
255    public void testMovePointLeftPos() {
256        String a = "1231212478987482988429808779810457634781384756794987";
257        int aScale = 28;
258        int shift = 18;
259        int resScale = 46;
260        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
261        BigDecimal bNumber = aNumber.movePointLeft(shift);
262        assertTrue("incorrect scale", bNumber.scale() == resScale);
263        assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(a));
264    }
265
266    /**
267     * Move the decimal point to the left; the shift value is positive
268     */
269    public void testMovePointLeftNeg() {
270        String a = "1231212478987482988429808779810457634781384756794987";
271        int aScale = 28;
272        int shift = -18;
273        int resScale = 10;
274        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
275        BigDecimal bNumber = aNumber.movePointLeft(shift);
276        assertTrue("incorrect scale", bNumber.scale() == resScale);
277        assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(a));
278    }
279
280    /**
281     * Move the decimal point to the right; the shift value is positive
282     */
283    public void testMovePointRightPosGreater() {
284        String a = "1231212478987482988429808779810457634781384756794987";
285        int aScale = 28;
286        int shift = 18;
287        int resScale = 10;
288        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
289        BigDecimal bNumber = aNumber.movePointRight(shift);
290        assertTrue("incorrect scale", bNumber.scale() == resScale);
291        assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(a));
292    }
293
294    /**
295     * Move the decimal point to the right; the shift value is positive
296     */
297    public void testMovePointRightPosLess() {
298        String a = "1231212478987482988429808779810457634781384756794987";
299        String b = "123121247898748298842980877981045763478138475679498700";
300        int aScale = 28;
301        int shift = 30;
302        int resScale = 0;
303        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
304        BigDecimal bNumber = aNumber.movePointRight(shift);
305        assertTrue("incorrect scale", bNumber.scale() == resScale);
306        assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(b));
307    }
308
309    /**
310     * Move the decimal point to the right; the shift value is positive
311     */
312    public void testMovePointRightNeg() {
313        String a = "1231212478987482988429808779810457634781384756794987";
314        int aScale = 28;
315        int shift = -18;
316        int resScale = 46;
317        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
318        BigDecimal bNumber = aNumber.movePointRight(shift);
319        assertTrue("incorrect scale", bNumber.scale() == resScale);
320        assertTrue("incorrect value", bNumber.unscaledValue().toString().equals(a));
321    }
322
323    /**
324     * Move the decimal point to the right when the scale overflows
325     */
326    public void testMovePointRightException() {
327        String a = "12312124789874829887348723648726347429808779810457634781384756794987";
328        int aScale = Integer.MAX_VALUE; //2147483647
329        int shift = -18;
330        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
331        try {
332            aNumber.movePointRight(shift);
333            fail("ArithmeticException has not been caught");
334        } catch (ArithmeticException e) {
335        }
336    }
337
338    /**
339     * precision()
340     */
341    public void testPrecision() {
342        String a = "12312124789874829887348723648726347429808779810457634781384756794987";
343        int aScale = 14;
344        BigDecimal aNumber = new BigDecimal(new BigInteger(a), aScale);
345        int prec = aNumber.precision();
346        assertEquals(68, prec);
347    }
348}
349