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 }