• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2012, 2016, 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 package test.java.lang.Math;
24 
25 import java.math.BigInteger;
26 
27 import org.testng.annotations.Test;
28 import org.testng.Assert;
29 
30 import static org.testng.Assert.fail;
31 
32 // Android-changed: Added test annotations, remove main() method.
33 
34 /**
35  * @author Roger Riggs
36  * @test Test for Math.*Exact integer and long methods.
37  * @bug 6708398
38  * @summary Basic tests for Math exact arithmetic operations.
39  */
40 public class ExactArithTests {
41 
42     /**
43      * Test Math.addExact, multiplyExact, subtractExact, toIntValue methods with {@code int}
44      * arguments.
45      */
46     @Test
testIntegerExact()47     public void testIntegerExact() {
48         testIntegerExact(0, 0);
49         testIntegerExact(1, 1);
50         testIntegerExact(1, -1);
51         testIntegerExact(-1, 1);
52         testIntegerExact(1000, 2000);
53 
54         testIntegerExact(Integer.MIN_VALUE, Integer.MIN_VALUE);
55         testIntegerExact(Integer.MAX_VALUE, Integer.MAX_VALUE);
56         testIntegerExact(Integer.MIN_VALUE, 1);
57         testIntegerExact(Integer.MAX_VALUE, 1);
58         testIntegerExact(Integer.MIN_VALUE, 2);
59         testIntegerExact(Integer.MAX_VALUE, 2);
60         testIntegerExact(Integer.MIN_VALUE, -1);
61         testIntegerExact(Integer.MAX_VALUE, -1);
62         testIntegerExact(Integer.MIN_VALUE, -2);
63         testIntegerExact(Integer.MAX_VALUE, -2);
64 
65     }
66 
67     /**
68      * Test exact arithmetic by comparing with the same operations using long and checking that the
69      * result is the same as the integer truncation. Errors are reported with {@link fail}.
70      *
71      * @param x first parameter
72      * @param y second parameter
73      */
testIntegerExact(int x, int y)74     static void testIntegerExact(int x, int y) {
75         try {
76             // Test addExact
77             int sum = Math.addExact(x, y);
78             long sum2 = (long) x + (long) y;
79             if ((int) sum2 != sum2) {
80                 fail("FAIL: int Math.addExact(" + x + " + " + y + ") = " + sum
81                         + "; expected Arithmetic exception");
82             } else if (sum != sum2) {
83                 fail("FAIL: long Math.addExact(" + x + " + " + y + ") = " + sum + "; expected: "
84                         + sum2);
85             }
86         } catch (ArithmeticException ex) {
87             long sum2 = (long) x + (long) y;
88             if ((int) sum2 == sum2) {
89                 fail("FAIL: int Math.addExact(" + x + " + " + y + ")" + "; Unexpected exception: "
90                         + ex);
91 
92             }
93         }
94 
95         try {
96             // Test subtractExact
97             int diff = Math.subtractExact(x, y);
98             long diff2 = (long) x - (long) y;
99             if ((int) diff2 != diff2) {
100                 fail("FAIL: int Math.subtractExact(" + x + " - " + y + ") = " + diff
101                         + "; expected: " + diff2);
102             }
103 
104         } catch (ArithmeticException ex) {
105             long diff2 = (long) x - (long) y;
106             if ((int) diff2 == diff2) {
107                 fail("FAIL: int Math.subtractExact(" + x + " - " + y + ")"
108                         + "; Unexpected exception: " + ex);
109             }
110         }
111 
112         try {
113             // Test multiplyExact
114             int product = Math.multiplyExact(x, y);
115             long m2 = (long) x * (long) y;
116             if ((int) m2 != m2) {
117                 fail("FAIL: int Math.multiplyExact(" + x + " * " + y + ") = " + product
118                         + "; expected: " + m2);
119             }
120         } catch (ArithmeticException ex) {
121             long m2 = (long) x * (long) y;
122             if ((int) m2 == m2) {
123                 fail("FAIL: int Math.multiplyExact(" + x + " * " + y + ")"
124                         + "; Unexpected exception: " + ex);
125             }
126         }
127 
128         try {
129             // Test incrementExact
130             int inc = Math.incrementExact(x);
131             long inc2 = (long) x + 1L;
132             if ((int) inc2 != inc2) {
133                 fail("FAIL: int Math.incrementExact(" + x + ") = " + inc
134                         + "; expected Arithmetic exception");
135             } else if (inc != inc2) {
136                 fail("FAIL: long Math.incrementExact(" + x + ") = " + inc + "; expected: " + inc2);
137             }
138         } catch (ArithmeticException ex) {
139             long inc2 = (long) x + 1L;
140             if ((int) inc2 == inc2) {
141                 fail("FAIL: int Math.incrementExact(" + x + ")" + "; Unexpected exception: " + ex);
142 
143             }
144         }
145 
146         try {
147             // Test decrementExact
148             int dec = Math.decrementExact(x);
149             long dec2 = (long) x - 1L;
150             if ((int) dec2 != dec2) {
151                 fail("FAIL: int Math.decrementExact(" + x + ") = " + dec
152                         + "; expected Arithmetic exception");
153             } else if (dec != dec2) {
154                 fail("FAIL: long Math.decrementExact(" + x + ") = " + dec + "; expected: " + dec2);
155             }
156         } catch (ArithmeticException ex) {
157             long dec2 = (long) x - 1L;
158             if ((int) dec2 == dec2) {
159                 fail("FAIL: int Math.decrementExact(" + x + ")" + "; Unexpected exception: " + ex);
160 
161             }
162         }
163 
164         try {
165             // Test negateExact
166             int neg = Math.negateExact(x);
167             long neg2 = -((long) x);
168             if ((int) neg2 != neg2) {
169                 fail("FAIL: int Math.negateExact(" + x + ") = " + neg
170                         + "; expected Arithmetic exception");
171             } else if (neg != neg2) {
172                 fail("FAIL: long Math.negateExact(" + x + ") = " + neg + "; expected: " + neg2);
173             }
174         } catch (ArithmeticException ex) {
175             long neg2 = (long) x - 1L;
176             if ((int) neg2 == neg2) {
177                 fail("FAIL: int Math.negateExact(" + x + ")" + "; Unexpected exception: " + ex);
178 
179             }
180         }
181     }
182 
183     /**
184      * Test Math.addExact, multiplyExact, subtractExact, toIntExact methods with {@code long}
185      * arguments.
186      */
187     @Test
testLongExact()188     static void testLongExact() {
189         testLongExactTwice(0, 0);
190         testLongExactTwice(1, 1);
191         testLongExactTwice(1, -1);
192         testLongExactTwice(1000, 2000);
193 
194         testLongExactTwice(Long.MIN_VALUE, Long.MIN_VALUE);
195         testLongExactTwice(Long.MAX_VALUE, Long.MAX_VALUE);
196         testLongExactTwice(Long.MIN_VALUE, 1);
197         testLongExactTwice(Long.MAX_VALUE, 1);
198         testLongExactTwice(Long.MIN_VALUE, 2);
199         testLongExactTwice(Long.MAX_VALUE, 2);
200         testLongExactTwice(Long.MIN_VALUE, -1);
201         testLongExactTwice(Long.MAX_VALUE, -1);
202         testLongExactTwice(Long.MIN_VALUE, -2);
203         testLongExactTwice(Long.MAX_VALUE, -2);
204         testLongExactTwice(Long.MIN_VALUE / 2, 2);
205         testLongExactTwice(Long.MAX_VALUE, 2);
206         testLongExactTwice(Integer.MAX_VALUE, Integer.MAX_VALUE);
207         testLongExactTwice(Integer.MAX_VALUE, -Integer.MAX_VALUE);
208         testLongExactTwice(Integer.MAX_VALUE + 1, Integer.MAX_VALUE + 1);
209         testLongExactTwice(Integer.MAX_VALUE + 1, -Integer.MAX_VALUE + 1);
210         testLongExactTwice(Integer.MIN_VALUE - 1, Integer.MIN_VALUE - 1);
211         testLongExactTwice(Integer.MIN_VALUE - 1, -Integer.MIN_VALUE - 1);
212         testLongExactTwice(Integer.MIN_VALUE / 2, 2);
213 
214     }
215 
216     /**
217      * Test each of the exact operations with the arguments and with the arguments reversed.
218      */
testLongExactTwice(long x, long y)219     static void testLongExactTwice(long x, long y) {
220         testLongExact(x, y);
221         testLongExact(y, x);
222     }
223 
224 
225     /**
226      * Test long exact arithmetic by comparing with the same operations using BigInteger and
227      * checking that the result is the same as the long truncation. Errors are reported with {@link
228      * fail}.
229      *
230      * @param x first parameter
231      * @param y second parameter
232      */
testLongExact(long x, long y)233     static void testLongExact(long x, long y) {
234         BigInteger resultBig = null;
235         final BigInteger xBig = BigInteger.valueOf(x);
236         final BigInteger yBig = BigInteger.valueOf(y);
237         try {
238             // Test addExact
239             resultBig = xBig.add(yBig);
240             long sum = Math.addExact(x, y);
241             checkResult("long Math.addExact", x, y, sum, resultBig);
242         } catch (ArithmeticException ex) {
243             if (inLongRange(resultBig)) {
244                 fail("FAIL: long Math.addExact(" + x + " + " + y + "); Unexpected exception: "
245                         + ex);
246             }
247         }
248 
249         try {
250             // Test subtractExact
251             resultBig = xBig.subtract(yBig);
252             long diff = Math.subtractExact(x, y);
253             checkResult("long Math.subtractExact", x, y, diff, resultBig);
254         } catch (ArithmeticException ex) {
255             if (inLongRange(resultBig)) {
256                 fail("FAIL: long Math.subtractExact(" + x + " - " + y + ")"
257                         + "; Unexpected exception: " + ex);
258             }
259         }
260 
261         try {
262             // Test multiplyExact
263             resultBig = xBig.multiply(yBig);
264             long product = Math.multiplyExact(x, y);
265             checkResult("long Math.multiplyExact", x, y, product, resultBig);
266         } catch (ArithmeticException ex) {
267             if (inLongRange(resultBig)) {
268                 fail("FAIL: long Math.multiplyExact(" + x + " * " + y + ")"
269                         + "; Unexpected exception: " + ex);
270             }
271         }
272 
273         try {
274             // Test incrementExact
275             resultBig = xBig.add(BigInteger.ONE);
276             long inc = Math.incrementExact(x);
277             checkResult("long Math.incrementExact", x, 1L, inc, resultBig);
278         } catch (ArithmeticException ex) {
279             if (inLongRange(resultBig)) {
280                 fail("FAIL: long Math.incrementExact(" + x + "); Unexpected exception: " + ex);
281             }
282         }
283 
284         try {
285             // Test decrementExact
286             resultBig = xBig.subtract(BigInteger.ONE);
287             long dec = Math.decrementExact(x);
288             checkResult("long Math.decrementExact", x, 1L, dec, resultBig);
289         } catch (ArithmeticException ex) {
290             if (inLongRange(resultBig)) {
291                 fail("FAIL: long Math.decrementExact(" + x + "); Unexpected exception: " + ex);
292             }
293         }
294 
295         try {
296             // Test negateExact
297             resultBig = xBig.negate();
298             long dec = Math.negateExact(x);
299             checkResult("long Math.negateExact", x, 0L, dec, resultBig);
300         } catch (ArithmeticException ex) {
301             if (inLongRange(resultBig)) {
302                 fail("FAIL: long Math.negateExact(" + x + "); Unexpected exception: " + ex);
303             }
304         }
305 
306         try {
307             // Test toIntExact
308             int value = Math.toIntExact(x);
309             if ((long) value != x) {
310                 fail("FAIL: " + "long Math.toIntExact" + "(" + x + ") = " + value
311                         + "; expected an arithmetic exception: ");
312             }
313         } catch (ArithmeticException ex) {
314             if (resultBig.bitLength() <= 32) {
315                 fail("FAIL: long Math.toIntExact(" + x + ")" + "; Unexpected exception: " + ex);
316             }
317         }
318 
319     }
320 
321     /**
322      * Compare the expected and actual results.
323      *
324      * @param message message for the error
325      * @param x first argument
326      * @param y second argument
327      * @param result actual result value
328      * @param expected expected result value
329      */
checkResult(String message, long x, long y, long result, BigInteger expected)330     static void checkResult(String message, long x, long y, long result, BigInteger expected) {
331         BigInteger resultBig = BigInteger.valueOf(result);
332         if (!inLongRange(expected)) {
333             fail("FAIL: " + message + "(" + x + ", " + y + ") = " + result
334                     + "; expected an arithmetic exception: ");
335         } else if (!resultBig.equals(expected)) {
336             fail("FAIL: " + message + "(" + x + ", " + y + ") = " + result + "; expected "
337                     + expected);
338         }
339     }
340 
341     /**
342      * Check if the value fits in 64 bits (a long).
343      *
344      * @return true if the value fits in 64 bits (including the sign).
345      */
inLongRange(BigInteger value)346     static boolean inLongRange(BigInteger value) {
347         return value.bitLength() <= 63;
348     }
349 
350     /**
351      * Test Math.multiplyExact method with {@code long} and {@code int} arguments.
352      */
353     @Test
testLongIntExact()354     static void testLongIntExact() {
355         testLongIntExact(0, 0);
356         testLongIntExact(1, 1);
357         testLongIntExact(1, -1);
358         testLongIntExact(1000, 2000);
359 
360         testLongIntExact(Long.MIN_VALUE, Integer.MIN_VALUE);
361         testLongIntExact(Long.MAX_VALUE, Integer.MAX_VALUE);
362         testLongIntExact(Long.MIN_VALUE, 1);
363         testLongIntExact(Long.MAX_VALUE, 1);
364         testLongIntExact(Long.MIN_VALUE, 2);
365         testLongIntExact(Long.MAX_VALUE, 2);
366         testLongIntExact(Long.MIN_VALUE, -1);
367         testLongIntExact(Long.MAX_VALUE, -1);
368         testLongIntExact(Long.MIN_VALUE, -2);
369         testLongIntExact(Long.MAX_VALUE, -2);
370         testLongIntExact(Long.MIN_VALUE / 2, 2);
371         testLongIntExact(Long.MAX_VALUE, 2);
372         testLongIntExact(Integer.MAX_VALUE, Integer.MAX_VALUE);
373         testLongIntExact(Integer.MAX_VALUE, -Integer.MAX_VALUE);
374         testLongIntExact((long) Integer.MAX_VALUE + 1L, Integer.MAX_VALUE);
375         testLongIntExact((long) Integer.MAX_VALUE + 1L, -Integer.MAX_VALUE + 1);
376         testLongIntExact((long) Integer.MIN_VALUE - 1L, Integer.MIN_VALUE);
377         testLongIntExact((long) Integer.MIN_VALUE - 1, Integer.MAX_VALUE);
378         testLongIntExact(Integer.MIN_VALUE / 2, 2);
379     }
380 
381     /**
382      * Test long-int exact arithmetic by comparing with the same operations using BigInteger and
383      * checking that the result is the same as the long truncation. Errors are reported with {@link
384      * fail}.
385      *
386      * @param x first parameter
387      * @param y second parameter
388      */
testLongIntExact(long x, int y)389     static void testLongIntExact(long x, int y) {
390         BigInteger resultBig = null;
391         final BigInteger xBig = BigInteger.valueOf(x);
392         final BigInteger yBig = BigInteger.valueOf(y);
393 
394         try {
395             // Test multiplyExact
396             resultBig = xBig.multiply(yBig);
397             long product = Math.multiplyExact(x, y);
398             checkResult("long Math.multiplyExact", x, y, product, resultBig);
399         } catch (ArithmeticException ex) {
400             if (inLongRange(resultBig)) {
401                 fail("FAIL: long Math.multiplyExact(" + x + " * " + y + ")"
402                         + "; Unexpected exception: " + ex);
403             }
404         }
405     }
406 }