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