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