1 /*
2  * Copyright (c) 2012, 2021, 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 
29 import static org.testng.Assert.fail;
30 
31 // Android-changed: Added test annotations, remove main() method.
32 
33 /**
34  * @test Test for Math.*Exact integer and long methods.
35  * @bug 6708398 8075806 8271225 8271602
36  * @summary Basic tests for Math exact arithmetic operations.
37  *
38  * @author Roger Riggs
39  */
40 public class ExactArithTests {
41     /**
42      * The count of test errors.
43      */
44     private static int errors = 0;
45 
46     /**
47      * @param args the command line arguments
48      */
49     // Android-changed: Added test annotations, remove main() method.
50     /*
51     public static void main(String[] args) {
52         testIntegerExact();
53         testLongExact();
54         testLongIntExact();
55 
56         if (errors > 0) {
57             throw new RuntimeException(errors + " errors found in ExactArithTests.");
58         }
59     }
60 
61     static void fail(String message) {
62         errors++;
63         System.err.println(message);
64     }
65     */
66 
67     /**
68      * Test Math.addExact, multiplyExact, divideExact, subtractExact,
69      * floorDivExact, ceilDivExact, incrementExact, decrementExact, negateExact
70      * methods with {@code int} arguments.
71      */
72     @Test
testIntegerExact()73     public void testIntegerExact() {
74         testIntegerExact(0, 0);
75         testIntegerExact(1, 1);
76         testIntegerExact(1, -1);
77         testIntegerExact(-1, 1);
78         testIntegerExact(1000, 2000);
79 
80         testIntegerExact(Integer.MIN_VALUE, Integer.MIN_VALUE);
81         testIntegerExact(Integer.MAX_VALUE, Integer.MAX_VALUE);
82         testIntegerExact(Integer.MIN_VALUE, 1);
83         testIntegerExact(Integer.MAX_VALUE, 1);
84         testIntegerExact(Integer.MIN_VALUE, 2);
85         testIntegerExact(Integer.MAX_VALUE, 2);
86         testIntegerExact(Integer.MIN_VALUE, -1);
87         testIntegerExact(Integer.MAX_VALUE, -1);
88         testIntegerExact(Integer.MIN_VALUE, -2);
89         testIntegerExact(Integer.MAX_VALUE, -2);
90     }
91 
92     /**
93      * Test exact arithmetic by comparing with the same operations using long
94      * and checking that the result is the same as the integer truncation.
95      *
96      * @param x first parameter
97      * @param y second parameter
98      */
testIntegerExact(int x, int y)99     static void testIntegerExact(int x, int y) {
100         try {
101             // Test addExact
102             int sum = Math.addExact(x, y);
103             long sum2 = (long) x + (long) y;
104             if ((int) sum2 != sum2) {
105                 fail("FAIL: int Math.addExact(" + x + " + " + y + ") = " + sum + "; expected Arithmetic exception");
106             } else if (sum != sum2) {
107                 fail("FAIL: long Math.addExact(" + x + " + " + y + ") = " + sum + "; expected: " + sum2);
108             }
109         } catch (ArithmeticException ex) {
110             long sum2 = (long) x + (long) y;
111             if ((int) sum2 == sum2) {
112                 fail("FAIL: int Math.addExact(" + x + " + " + y + ")" + "; Unexpected exception: " + ex);
113             }
114         }
115 
116         try {
117             // Test subtractExact
118             int diff = Math.subtractExact(x, y);
119             long diff2 = (long) x - (long) y;
120             if ((int) diff2 != diff2) {
121                 fail("FAIL: int Math.subtractExact(" + x + " - " + y + ") = " + diff + "; expected: " + diff2);
122             }
123 
124         } catch (ArithmeticException ex) {
125             long diff2 = (long) x - (long) y;
126             if ((int) diff2 == diff2) {
127                 fail("FAIL: int Math.subtractExact(" + x + " - " + y + ")" + "; Unexpected exception: " + ex);
128             }
129         }
130 
131         try {
132             // Test multiplyExact
133             int product = Math.multiplyExact(x, y);
134             long m2 = (long) x * (long) y;
135             if ((int) m2 != m2) {
136                 fail("FAIL: int Math.multiplyExact(" + x + " * " + y + ") = " + product + "; expected: " + m2);
137             }
138         } catch (ArithmeticException ex) {
139             long m2 = (long) x * (long) y;
140             if ((int) m2 == m2) {
141                 fail("FAIL: int Math.multiplyExact(" + x + " * " + y + ")" + "; Unexpected exception: " + ex);
142             }
143         }
144 
145         boolean exceptionExpected = false;
146         try {
147             // Test divideExact
148             BigInteger q = null;
149             try {
150                 q = BigInteger.valueOf(x).divide(BigInteger.valueOf(y));
151             } catch (ArithmeticException e) {
152                 exceptionExpected = true;
153             }
154             int quotient = 0;
155             if (q != null) {
156                 try {
157                     quotient = q.intValueExact();
158                 } catch (ArithmeticException e) {
159                     exceptionExpected = true;
160                 }
161             }
162             int z = Math.divideExact(x, y);
163             if (exceptionExpected) {
164                 fail("FAIL: int Math.divideExact(" + x + " / " + y + ")" +
165                     "; expected ArithmeticException not thrown");
166             }
167             if (z != quotient) {
168                 fail("FAIL: int Math.divideExact(" + x + " / " + y + ") = " +
169                     z + "; expected: " + quotient);
170             }
171             // Android-added: Test functionally-equivalent StrictMath version.
172             z = StrictMath.divideExact(x, y);
173             if (z != quotient) {
174                 fail("FAIL: int StrictMath.divideExact(" + x + " / " + y + ") = " +
175                         z + "; expected: " + q);
176             }
177         } catch (ArithmeticException ex) {
178             if (!exceptionExpected) {
179                 fail("FAIL: int Math.divideExact(" + x + " / " + y + ")" +
180                     "; Unexpected exception: " + ex);
181             }
182         }
183 
184         exceptionExpected = false;
185         try {
186             // Test floorDivExact
187             int q = 0;
188             try {
189                 q = Math.floorDiv(x, y);
190             } catch (ArithmeticException e) {
191                 exceptionExpected = true;
192             }
193             if (!exceptionExpected && x == Integer.MIN_VALUE && y == -1) {
194                 exceptionExpected = true;
195             }
196             int z = Math.floorDivExact(x, y);
197             if (exceptionExpected) {
198                 fail("FAIL: int Math.floorDivExact(" + x + " / " + y + ")" +
199                     "; expected ArithmeticException not thrown");
200             }
201             if (z != q) {
202                 fail("FAIL: int Math.floorDivExact(" + x + " / " + y + ") = " +
203                     z + "; expected: " + q);
204             }
205             // Android-added: Test functionally-equivalent StrictMath version.
206             z = StrictMath.floorDivExact(x, y);
207             if (z != q) {
208                 fail("FAIL: int StrictMath.floorDivExact(" + x + " / " + y + ") = " +
209                         z + "; expected: " + q);
210             }
211         } catch (ArithmeticException ex) {
212             if (!exceptionExpected) {
213                 fail("FAIL: int Math.floorDivExact(" + x + " / " + y + ")" +
214                     "; Unexpected exception: " + ex);
215             }
216         }
217 
218         exceptionExpected = false;
219         try {
220             // Test ceilDivExact
221             int q = 0;
222             try {
223                 q = Math.ceilDiv(x, y);
224             } catch (ArithmeticException e) {
225                 exceptionExpected = true;
226             }
227             if (!exceptionExpected && x == Integer.MIN_VALUE && y == -1) {
228                 exceptionExpected = true;
229             }
230             int z = Math.ceilDivExact(x, y);
231             if (exceptionExpected) {
232                 fail("FAIL: int Math.ceilDivExact(" + x + " / " + y + ")" +
233                         "; expected ArithmeticException not thrown");
234             }
235             if (z != q) {
236                 fail("FAIL: int Math.ceilDivExact(" + x + " / " + y + ") = " +
237                         z + "; expected: " + q);
238             }
239             // Android-added: Test functionally-equivalent StrictMath version.
240             if (z != StrictMath.ceilDivExact(x, y)) {
241                 fail("FAIL: int StrictMath.ceilDivExact(" + x + " / " + y + ") = " +
242                         z + "; expected: " + q);
243             }
244         } catch (ArithmeticException ex) {
245             if (!exceptionExpected) {
246                 fail("FAIL: int Math.ceilDivExact(" + x + " / " + y + ")" +
247                         "; Unexpected exception: " + ex);
248             }
249         }
250 
251         try {
252             // Test incrementExact
253             int inc = Math.incrementExact(x);
254             long inc2 = (long) x + 1L;
255             if ((int) inc2 != inc2) {
256                 fail("FAIL: int Math.incrementExact(" + x + ") = " + inc + "; expected Arithmetic exception");
257             } else if (inc != inc2) {
258                 fail("FAIL: long Math.incrementExact(" + x + ") = " + inc + "; expected: " + inc2);
259             }
260         } catch (ArithmeticException ex) {
261             long inc2 = (long) x + 1L;
262             if ((int) inc2 == inc2) {
263                 fail("FAIL: int Math.incrementExact(" + x + ")" + "; Unexpected exception: " + ex);
264             }
265         }
266 
267         try {
268             // Test decrementExact
269             int dec = Math.decrementExact(x);
270             long dec2 = (long) x - 1L;
271             if ((int) dec2 != dec2) {
272                 fail("FAIL: int Math.decrementExact(" + x + ") = " + dec + "; expected Arithmetic exception");
273             } else if (dec != dec2) {
274                 fail("FAIL: long Math.decrementExact(" + x + ") = " + dec + "; expected: " + dec2);
275             }
276         } catch (ArithmeticException ex) {
277             long dec2 = (long) x - 1L;
278             if ((int) dec2 == dec2) {
279                 fail("FAIL: int Math.decrementExact(" + x + ")" + "; Unexpected exception: " + ex);
280             }
281         }
282 
283         try {
284             // Test negateExact
285             int neg = Math.negateExact(x);
286             long neg2 = -((long)x);
287             if ((int) neg2 != neg2) {
288                 fail("FAIL: int Math.negateExact(" + x + ") = " + neg + "; expected Arithmetic exception");
289             } else if (neg != neg2) {
290                 fail("FAIL: long Math.negateExact(" + x + ") = " + neg + "; expected: " + neg2);
291             }
292         } catch (ArithmeticException ex) {
293             long neg2 = -((long)x);
294             if ((int) neg2 == neg2) {
295                 fail("FAIL: int Math.negateExact(" + x + ")" + "; Unexpected exception: " + ex);
296             }
297         }
298     }
299 
300     /**
301      * Test Math.addExact, multiplyExact, divideExact, subtractExact,
302      * floorDivExact, ceilDivExact, incrementExact, decrementExact, negateExact, toIntExact
303      * methods with {@code long} arguments.
304      */
305     @Test
testLongExact()306     public void testLongExact() {
307         testLongExactTwice(0, 0);
308         testLongExactTwice(1, 1);
309         testLongExactTwice(1, -1);
310         testLongExactTwice(1000, 2000);
311 
312         testLongExactTwice(Long.MIN_VALUE, Long.MIN_VALUE);
313         testLongExactTwice(Long.MAX_VALUE, Long.MAX_VALUE);
314         testLongExactTwice(Long.MIN_VALUE, 1);
315         testLongExactTwice(Long.MAX_VALUE, 1);
316         testLongExactTwice(Long.MIN_VALUE, 2);
317         testLongExactTwice(Long.MAX_VALUE, 2);
318         testLongExactTwice(Long.MIN_VALUE, -1);
319         testLongExactTwice(Long.MAX_VALUE, -1);
320         testLongExactTwice(Long.MIN_VALUE, -2);
321         testLongExactTwice(Long.MAX_VALUE, -2);
322         testLongExactTwice(Long.MIN_VALUE / 2, 2);
323         testLongExactTwice(Long.MAX_VALUE, 2);
324         testLongExactTwice(Integer.MAX_VALUE, Integer.MAX_VALUE);
325         testLongExactTwice(Integer.MAX_VALUE, -Integer.MAX_VALUE);
326         testLongExactTwice(Integer.MAX_VALUE + 1, Integer.MAX_VALUE + 1);
327         testLongExactTwice(Integer.MAX_VALUE + 1, -Integer.MAX_VALUE + 1);
328         testLongExactTwice(Integer.MIN_VALUE - 1, Integer.MIN_VALUE - 1);
329         testLongExactTwice(Integer.MIN_VALUE - 1, -Integer.MIN_VALUE - 1);
330         testLongExactTwice(Integer.MIN_VALUE / 2, 2);
331 
332     }
333 
334     /**
335      * Test each of the exact operations with the arguments and
336      * with the arguments reversed.
337      * @param x
338      * @param y
339      */
testLongExactTwice(long x, long y)340     static void testLongExactTwice(long x, long y) {
341         testLongExact(x, y);
342         testLongExact(y, x);
343     }
344 
345 
346     /**
347      * Test long exact arithmetic by comparing with the same operations using BigInteger
348      * and checking that the result is the same as the long truncation.
349      *
350      * @param x first parameter
351      * @param y second parameter
352      */
testLongExact(long x, long y)353     static void testLongExact(long x, long y) {
354         BigInteger resultBig = null;
355         final BigInteger xBig = BigInteger.valueOf(x);
356         final BigInteger yBig = BigInteger.valueOf(y);
357         try {
358             // Test addExact
359             resultBig = xBig.add(yBig);
360             long sum = Math.addExact(x, y);
361             checkResult("long Math.addExact", x, y, sum, resultBig);
362         } catch (ArithmeticException ex) {
363             if (inLongRange(resultBig)) {
364                 fail("FAIL: long Math.addExact(" + x + " + " + y + "); Unexpected exception: " + ex);
365             }
366         }
367 
368         try {
369             // Test subtractExact
370             resultBig = xBig.subtract(yBig);
371             long diff = Math.subtractExact(x, y);
372             checkResult("long Math.subtractExact", x, y, diff, resultBig);
373         } catch (ArithmeticException ex) {
374             if (inLongRange(resultBig)) {
375                 fail("FAIL: long Math.subtractExact(" + x + " - " + y + ")" + "; Unexpected exception: " + ex);
376             }
377         }
378 
379         try {
380             // Test multiplyExact
381             resultBig = xBig.multiply(yBig);
382             long product = Math.multiplyExact(x, y);
383             checkResult("long Math.multiplyExact", x, y, product, resultBig);
384         } catch (ArithmeticException ex) {
385             if (inLongRange(resultBig)) {
386                 fail("FAIL: long Math.multiplyExact(" + x + " * " + y + ")" + "; Unexpected exception: " + ex);
387             }
388         }
389 
390         try {
391             // Test divideExact
392             resultBig = null;
393             try {
394                 resultBig = xBig.divide(yBig);
395             } catch (ArithmeticException ex) {
396             }
397             long quotient = Math.divideExact(x, y);
398             if (resultBig == null) {
399                 fail("FAIL: long Math.divideExact(" + x + " / " + y + ")" +
400                     "; expected ArithmeticException not thrown");
401             }
402             checkResult("long Math.divideExact", x, y, quotient, resultBig);
403             // Android-added: Test functionally-equivalent StrictMath version.
404             long quotient2 = StrictMath.divideExact(x, y);
405             if (quotient2 != quotient) {
406                 fail("FAIL: long StrictMath.divideExact(" + x + " / " + y + ")" +
407                         "; expected " + quotient + " but got " + quotient2);
408             }
409             checkResult("long StrictMath.divideExact", x, y, quotient2, resultBig);
410         } catch (ArithmeticException ex) {
411             if (resultBig != null && inLongRange(resultBig)) {
412                 fail("FAIL: long Math.divideExact(" + x + " / " + y + ")" +
413                     "; Unexpected exception: " + ex);
414             }
415         }
416 
417         boolean exceptionExpected = false;
418         try {
419             // Test floorDivExact
420             long q = 0;
421             try {
422                 q = Math.floorDiv(x, y);
423             } catch (ArithmeticException e) {
424                 exceptionExpected = true;
425             }
426             if (!exceptionExpected && x == Long.MIN_VALUE && y == -1) {
427                 exceptionExpected = true;
428             }
429             long z = Math.floorDivExact(x, y);
430             if (exceptionExpected) {
431                 fail("FAIL: long Math.floorDivExact(" + x + " / " + y + ")" +
432                     "; expected ArithmeticException not thrown");
433             }
434             if (z != q) {
435                 fail("FAIL: long Math.floorDivExact(" + x + " / " + y + ") = " +
436                     z + "; expected: " + q);
437             }
438             // Android-added: Test functionally-equivalent StrictMath version.
439             z = StrictMath.floorDivExact(x, y);
440             if (z != q) {
441                 fail("FAIL: long StrictMath.floorDivExact(" + x + " / " + y + ") = " +
442                         z + "; expected: " + q);
443             }
444         } catch (ArithmeticException ex) {
445             if (!exceptionExpected) {
446                 fail("FAIL: long Math.floorDivExact(" + x + " / " + y + ")" +
447                     "; Unexpected exception: " + ex);
448             }
449         }
450 
451         exceptionExpected = false;
452         try {
453             // Test ceilDivExact
454             long q = 0;
455             try {
456                 q = Math.ceilDiv(x, y);
457             } catch (ArithmeticException e) {
458                 exceptionExpected = true;
459             }
460             if (!exceptionExpected && x == Long.MIN_VALUE && y == -1) {
461                 exceptionExpected = true;
462             }
463             long z = Math.ceilDivExact(x, y);
464             if (exceptionExpected) {
465                 fail("FAIL: long Math.ceilDivExact(" + x + " / " + y + ")" +
466                         "; expected ArithmeticException not thrown");
467             }
468             if (z != q) {
469                 fail("FAIL: long Math.ceilDivExact(" + x + " / " + y + ") = " +
470                         z + "; expected: " + q);
471             }
472             // Android-added: Test functionally-equivalent StrictMath version.
473             z = StrictMath.ceilDivExact(x, y);
474             if (z != q) {
475                 fail("FAIL: long StrictMath.ceilDivExact(" + x + " / " + y + ") = " +
476                         z + "; expected: " + q);
477             }
478         } catch (ArithmeticException ex) {
479             if (!exceptionExpected) {
480                 fail("FAIL: long Math.ceilDivExact(" + x + " / " + y + ")" +
481                         "; Unexpected exception: " + ex);
482             }
483         }
484 
485         try {
486             // Test incrementExact
487             resultBig = xBig.add(BigInteger.ONE);
488             long inc = Math.incrementExact(x);
489             checkResult("long Math.incrementExact", x, 1L, inc, resultBig);
490         } catch (ArithmeticException ex) {
491             if (inLongRange(resultBig)) {
492                 fail("FAIL: long Math.incrementExact(" + x + "); Unexpected exception: " + ex);
493             }
494         }
495 
496         try {
497             // Test decrementExact
498             resultBig = xBig.subtract(BigInteger.ONE);
499             long dec = Math.decrementExact(x);
500             checkResult("long Math.decrementExact", x, 1L, dec, resultBig);
501         } catch (ArithmeticException ex) {
502             if (inLongRange(resultBig)) {
503                 fail("FAIL: long Math.decrementExact(" + x + "); Unexpected exception: " + ex);
504             }
505         }
506 
507         try {
508             // Test negateExact
509             resultBig = xBig.negate();
510             long dec = Math.negateExact(x);
511             checkResult("long Math.negateExact", x, 0L, dec, resultBig);
512         } catch (ArithmeticException ex) {
513             if (inLongRange(resultBig)) {
514                 fail("FAIL: long Math.negateExact(" + x + "); Unexpected exception: " + ex);
515             }
516         }
517 
518         try {
519             // Test toIntExact
520             int value = Math.toIntExact(x);
521             if ((long)value != x) {
522                 fail("FAIL: " + "long Math.toIntExact" + "(" + x + ") = " + value + "; expected an arithmetic exception: ");
523             }
524         } catch (ArithmeticException ex) {
525             if (resultBig.bitLength() <= 32) {
526                 fail("FAIL: long Math.toIntExact(" + x + ")" + "; Unexpected exception: " + ex);
527             }
528         }
529     }
530 
531     /**
532      * Compare the expected and actual results.
533      * @param message message for the error
534      * @param x first argument
535      * @param y second argument
536      * @param result actual result value
537      * @param expected expected result value
538      */
checkResult(String message, long x, long y, long result, BigInteger expected)539     static void checkResult(String message, long x, long y, long result, BigInteger expected) {
540         BigInteger resultBig = BigInteger.valueOf(result);
541         if (!inLongRange(expected)) {
542             fail("FAIL: " + message + "(" + x + ", " + y + ") = " + result + "; expected an arithmetic exception: ");
543         } else if (!resultBig.equals(expected)) {
544             fail("FAIL: " + message + "(" + x + ", " + y + ") = " + result + "; expected " + expected);
545         }
546     }
547 
548     /**
549      * Check if the value fits in 64 bits (a long).
550      * @param value
551      * @return true if the value fits in 64 bits (including the sign).
552      */
inLongRange(BigInteger value)553     static boolean inLongRange(BigInteger value) {
554         return value.bitLength() <= 63;
555     }
556 
557     /**
558      * Test Math.multiplyExact method with {@code long} and {@code int}
559      * arguments.
560      */
561     @Test
testLongIntExact()562     public void testLongIntExact() {
563         testLongIntExact(0, 0);
564         testLongIntExact(1, 1);
565         testLongIntExact(1, -1);
566         testLongIntExact(1000, 2000);
567 
568         testLongIntExact(Long.MIN_VALUE, Integer.MIN_VALUE);
569         testLongIntExact(Long.MAX_VALUE, Integer.MAX_VALUE);
570         testLongIntExact(Long.MIN_VALUE, 1);
571         testLongIntExact(Long.MAX_VALUE, 1);
572         testLongIntExact(Long.MIN_VALUE, 2);
573         testLongIntExact(Long.MAX_VALUE, 2);
574         testLongIntExact(Long.MIN_VALUE, -1);
575         testLongIntExact(Long.MAX_VALUE, -1);
576         testLongIntExact(Long.MIN_VALUE, -2);
577         testLongIntExact(Long.MAX_VALUE, -2);
578         testLongIntExact(Long.MIN_VALUE / 2, 2);
579         testLongIntExact(Long.MAX_VALUE, 2);
580         testLongIntExact(Integer.MAX_VALUE, Integer.MAX_VALUE);
581         testLongIntExact(Integer.MAX_VALUE, -Integer.MAX_VALUE);
582         testLongIntExact((long) Integer.MAX_VALUE + 1L, Integer.MAX_VALUE);
583         testLongIntExact((long) Integer.MAX_VALUE + 1L, -Integer.MAX_VALUE + 1);
584         testLongIntExact((long) Integer.MIN_VALUE - 1L, Integer.MIN_VALUE);
585         testLongIntExact((long) Integer.MIN_VALUE - 1, Integer.MAX_VALUE);
586         testLongIntExact(Integer.MIN_VALUE / 2, 2);
587     }
588 
589     /**
590      * Test long-int exact arithmetic by comparing with the same operations using BigInteger
591      * and checking that the result is the same as the long truncation.
592      *
593      * @param x first parameter
594      * @param y second parameter
595      */
testLongIntExact(long x, int y)596     static void testLongIntExact(long x, int y) {
597         BigInteger resultBig = null;
598         final BigInteger xBig = BigInteger.valueOf(x);
599         final BigInteger yBig = BigInteger.valueOf(y);
600 
601         try {
602             // Test multiplyExact
603             resultBig = xBig.multiply(yBig);
604             long product = Math.multiplyExact(x, y);
605             checkResult("long Math.multiplyExact", x, y, product, resultBig);
606         } catch (ArithmeticException ex) {
607             if (inLongRange(resultBig)) {
608                 fail("FAIL: long Math.multiplyExact(" + x + " * " + y + ")" + "; Unexpected exception: " + ex);
609             }
610         }
611     }
612 }
613