1/*
2 * Copyright (c) 2003, 2011, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation.
8 *
9 * This code is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12 * version 2 for more details (a copy is included in the LICENSE file that
13 * accompanied this code).
14 *
15 * You should have received a copy of the GNU General Public License version
16 * 2 along with this work; if not, write to the Free Software Foundation,
17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18 *
19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20 * or visit www.oracle.com if you need additional information or have any
21 * questions.
22 */
23
24/*
25 * @test
26 * @bug 7036582
27 * @summary Some new tests for the add method and constructor with MathContext.
28 * @run main RangeTests
29 * @run main/othervm -XX:+AggressiveOpts RangeTests
30 * @author Sergey V. Kuksenko
31 */
32
33import java.math.BigDecimal;
34import java.math.BigInteger;
35import java.math.MathContext;
36
37public class RangeTests {
38
39
40    private static int addTest(BigDecimal arg1, BigDecimal arg2, BigDecimal expectedResult) {
41        int failures = 0;
42        BigDecimal result = arg1.add(arg2);
43        if (!result.equals(expectedResult)) {
44            System.out.println("Sum:" +
45                    arg1 + " + " +
46                    arg2 + " == " +
47                    result + "; expected  " +
48                    expectedResult
49            );
50            failures++;
51        }
52        result = arg2.add(arg1);
53        if (!result.equals(expectedResult)) {
54            System.out.println("Sum:" +
55                    arg2 + " + " +
56                    arg1 + " == " +
57                    result + "; expected  " +
58                    expectedResult
59            );
60            failures++;
61        }
62        return failures;
63    }
64
65    /*
66     *  Test BigDecimal.add(BigDecimal) when values are withing different ranges:
67     *  1. within 32 bits
68     *  2. within 64 bits
69     *  3. outside 64 bits.
70     */
71    private static int addBoundaryTest() {
72        int failures = 0;
73        failures += addTest(
74                new BigDecimal("85070591730234615847396907784232501249"),
75                BigDecimal.valueOf(0),
76                new BigDecimal("85070591730234615847396907784232501249") );
77        failures += addTest(
78                new BigDecimal("-85070591730234615847396907784232501249"),
79                BigDecimal.valueOf(0),
80                new BigDecimal("-85070591730234615847396907784232501249") );
81        failures += addTest(
82                new BigDecimal("85070591730234615847396907784232501249"),
83                BigDecimal.valueOf(1),
84                new BigDecimal("85070591730234615847396907784232501250") );
85        failures += addTest(
86                new BigDecimal("85070591730234615847396907784232501249"),
87                BigDecimal.valueOf(-1),
88                new BigDecimal("85070591730234615847396907784232501248") );
89        failures += addTest(
90                new BigDecimal("-85070591730234615847396907784232501250"),
91                BigDecimal.valueOf(-1),
92                new BigDecimal("-85070591730234615847396907784232501251") );
93        failures += addTest(
94                new BigDecimal("-85070591730234615847396907784232501249"),
95                BigDecimal.valueOf(1),
96                new BigDecimal("-85070591730234615847396907784232501248") );
97        failures += addTest(
98                new BigDecimal("147573952589676412927"),
99                BigDecimal.valueOf(Integer.MAX_VALUE),
100                new BigDecimal("147573952591823896574") );
101        failures += addTest(
102                new BigDecimal("-147573952589676412927"),
103                BigDecimal.valueOf(Integer.MAX_VALUE),
104                new BigDecimal("-147573952587528929280") );
105        failures += addTest(
106                new BigDecimal("79228162514264337593543950335"),
107                BigDecimal.valueOf(999),
108                new BigDecimal("79228162514264337593543951334") );
109        failures += addTest(
110                new BigDecimal("79228162514264337593543950335"),
111                BigDecimal.valueOf(Integer.MAX_VALUE/2),
112                new BigDecimal("79228162514264337594617692158") );
113        failures += addTest(
114                new BigDecimal("79228162514264337593543950335"),
115                BigDecimal.valueOf(Integer.MIN_VALUE/2),
116                new BigDecimal("79228162514264337592470208511") );
117        failures += addTest(
118                new BigDecimal("-79228162514264337593543950335"),
119                BigDecimal.valueOf(Integer.MAX_VALUE/2),
120                new BigDecimal("-79228162514264337592470208512") );
121        failures += addTest(
122                new BigDecimal("79228162514264337593543950335"),
123                BigDecimal.valueOf(-(Integer.MIN_VALUE/2)),
124                new BigDecimal("79228162514264337594617692159") );
125        failures += addTest(
126                new BigDecimal("79228162514264337593543950335"),
127                BigDecimal.valueOf(Long.MAX_VALUE/2),
128                new BigDecimal("79228162518876023611971338238") );
129        failures += addTest(
130                new BigDecimal("79228162514264337593543950335"),
131                BigDecimal.valueOf(Long.MIN_VALUE/2),
132                new BigDecimal("79228162509652651575116562431") );
133        failures += addTest(
134                new BigDecimal("-79228162514264337593543950335"),
135                BigDecimal.valueOf(Long.MAX_VALUE/2),
136                new BigDecimal("-79228162509652651575116562432") );
137        failures += addTest(
138                new BigDecimal("79228162514264337593543950335"),
139                BigDecimal.valueOf(-(Long.MIN_VALUE/2)),
140                new BigDecimal("79228162518876023611971338239") );
141        failures += addTest(
142                new BigDecimal("-9223372036854775808"),
143                BigDecimal.valueOf(1),
144                new BigDecimal("-9223372036854775807") );
145        failures += addTest(
146                new BigDecimal("-9223372036854775808"),
147                BigDecimal.valueOf(Long.MAX_VALUE/2),
148                new BigDecimal("-4611686018427387905") );
149        failures += addTest(
150                new BigDecimal("9223372036854775808"),
151                BigDecimal.valueOf(-1),
152                new BigDecimal("9223372036854775807") );
153        failures += addTest(
154                new BigDecimal("9223372036854775808"),
155                BigDecimal.valueOf(-Long.MAX_VALUE/2),
156                new BigDecimal("4611686018427387905") );
157
158        return failures;
159    }
160
161    private static int testRoundingFromBigInteger(BigInteger bi, int scale, MathContext mc) {
162        int failures = 0;
163        BigDecimal bd1 = new BigDecimal(bi,scale, mc);
164        BigDecimal bd2 = (new BigDecimal(bi,scale)).round(mc);
165        if (!bd1.equals(bd2)) {
166            System.out.println("new BigDecimal(BigInteger,int,MathContext):" +
167                    "BigInteger == " +
168                    bi + ";  scale == " + scale + "; result == " +
169                    bd1 + "; expected  == " +
170                    bd2
171            );
172            failures++;
173        }
174        return failures;
175    }
176
177    private static int roundingConstructorTest() {
178        int failures = 0;
179        failures += testRoundingFromBigInteger(
180                new BigInteger("85070591730234615847396907784232501249"),
181                7, MathContext.DECIMAL64);
182        failures += testRoundingFromBigInteger(
183                new BigInteger("85070591730234615847396907784232501249"),
184                0, MathContext.DECIMAL64);
185        failures += testRoundingFromBigInteger(
186                new BigInteger("85070591730234615847396907784232501249"),
187                -7, MathContext.DECIMAL64);
188        failures += testRoundingFromBigInteger(
189                new BigInteger("85070591730234615847396907784232501249"),
190                7, MathContext.DECIMAL128);
191        failures += testRoundingFromBigInteger(
192                new BigInteger("85070591730234615847396907784232501249"),
193                177, MathContext.DECIMAL128);
194        failures += testRoundingFromBigInteger(
195                new BigInteger("85070591730234615847396907784232501249"),
196                177, MathContext.DECIMAL32);
197        failures += testRoundingFromBigInteger(
198                new BigInteger("85070591730234615847396907784232501249"),
199                177, MathContext.UNLIMITED);
200        failures += testRoundingFromBigInteger(
201                new BigInteger("85070591730234615847396907784232501249"),
202                0, MathContext.UNLIMITED);
203        return failures;
204    }
205
206    private static int minLongConstructorTest(MathContext mc) {
207        int failures = 0;
208        BigDecimal bd1 = new BigDecimal(Long.MIN_VALUE,mc);
209        BigDecimal bd2 = new BigDecimal(Long.MIN_VALUE).round(mc);
210        if (!bd1.equals(bd2)) {
211            System.out.println("new BigDecimal(long,MathContext):" +
212                    "long == " +
213                    Long.MIN_VALUE + "; result == " +
214                    bd1 + "; expected  == " +
215                    bd2
216            );
217            failures++;
218        }
219        return failures;
220    }
221
222    private static int minLongConstructorTest() {
223        int failures = 0;
224        failures+=minLongConstructorTest(MathContext.UNLIMITED);
225        failures+=minLongConstructorTest(MathContext.DECIMAL32);
226        failures+=minLongConstructorTest(MathContext.DECIMAL64);
227        failures+=minLongConstructorTest(MathContext.DECIMAL128);
228        return failures;
229    }
230
231    public static void main(String argv[]) {
232        int failures = 0;
233
234        failures += addBoundaryTest();
235        failures += roundingConstructorTest();
236        failures += minLongConstructorTest();
237        if (failures > 0) {
238            throw new RuntimeException("Incurred " + failures +
239                                       " failures while testing.");
240        }
241    }
242
243
244
245}
246