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