1 /* 2 * Copyright (c) 2003, 2017, 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 24 /* 25 * @test 26 * @library /test/lib 27 * @build jdk.test.lib.RandomFactory 28 * @run main IeeeRecommendedTests 29 * @bug 4860891 4826732 4780454 4939441 4826652 8078672 30 * @summary Tests for IEEE 754[R] recommended functions and similar methods (use -Dseed=X to set PRNG seed) 31 * @author Joseph D. Darcy 32 * @key randomness 33 */ 34 package test.java.lang.Math; 35 36 import java.util.Random; 37 38 import org.testng.annotations.Test; 39 40 public class IeeeRecommendedTests { 41 IeeeRecommendedTests()42 private IeeeRecommendedTests() { 43 } 44 45 static final float NaNf = Float.NaN; 46 static final double NaNd = Double.NaN; 47 static final float infinityF = Float.POSITIVE_INFINITY; 48 static final double infinityD = Double.POSITIVE_INFINITY; 49 50 static final float Float_MAX_VALUEmm = 0x1.fffffcP+127f; 51 static final float Float_MAX_SUBNORMAL = 0x0.fffffeP-126f; 52 static final float Float_MAX_SUBNORMALmm = 0x0.fffffcP-126f; 53 54 static final double Double_MAX_VALUEmm = 0x1.ffffffffffffeP+1023; 55 static final double Double_MAX_SUBNORMAL = 0x0.fffffffffffffP-1022; 56 static final double Double_MAX_SUBNORMALmm = 0x0.ffffffffffffeP-1022; 57 58 // Initialize shared random number generator 59 static java.util.Random rand = new Random(); 60 61 /** 62 * Returns a floating-point power of two in the normal range. 63 */ powerOfTwoD(int n)64 static double powerOfTwoD(int n) { 65 return Double.longBitsToDouble((((long) n + (long) Double.MAX_EXPONENT) << 66 (DoubleConsts.SIGNIFICAND_WIDTH - 1)) 67 & DoubleConsts.EXP_BIT_MASK); 68 } 69 70 /** 71 * Returns a floating-point power of two in the normal range. 72 */ powerOfTwoF(int n)73 static float powerOfTwoF(int n) { 74 return Float.intBitsToFloat(((n + Float.MAX_EXPONENT) << 75 (FloatConsts.SIGNIFICAND_WIDTH - 1)) 76 & FloatConsts.EXP_BIT_MASK); 77 } 78 79 /* ******************** getExponent tests ****************************** */ 80 81 /* 82 * The tests for getExponent should test the special values (NaN, +/- 83 * infinity, etc.), test the endpoints of each binade (set of 84 * floating-point values with the same exponent), and for good 85 * measure, test some random values within each binade. Testing 86 * the endpoints of each binade includes testing both positive and 87 * negative numbers. Subnormal values with different normalized 88 * exponents should be tested too. Both Math and StrictMath 89 * methods should return the same results. 90 */ 91 92 /* 93 * Test Math.getExponent and StrictMath.getExponent with +d and -d. 94 */ testGetExponentCase(float f, int expected)95 static void testGetExponentCase(float f, int expected) { 96 float minus_f = -f; 97 98 Tests.test("Math.getExponent(float)", f, 99 Math.getExponent(f), expected); 100 Tests.test("Math.getExponent(float)", minus_f, 101 Math.getExponent(minus_f), expected); 102 103 Tests.test("StrictMath.getExponent(float)", f, 104 StrictMath.getExponent(f), expected); 105 Tests.test("StrictMath.getExponent(float)", minus_f, 106 StrictMath.getExponent(minus_f), expected); 107 } 108 109 /* 110 * Test Math.getExponent and StrictMath.getExponent with +d and -d. 111 */ testGetExponentCase(double d, int expected)112 static void testGetExponentCase(double d, int expected) { 113 double minus_d = -d; 114 115 Tests.test("Math.getExponent(double)", d, 116 Math.getExponent(d), expected); 117 Tests.test("Math.getExponent(double)", minus_d, 118 Math.getExponent(minus_d), expected); 119 120 Tests.test("StrictMath.getExponent(double)", d, 121 StrictMath.getExponent(d), expected); 122 Tests.test("StrictMath.getExponent(double)", minus_d, 123 StrictMath.getExponent(minus_d), expected); 124 } 125 126 @Test testFloatGetExponent()127 public void testFloatGetExponent() { 128 float[] specialValues = {NaNf, 129 Float.POSITIVE_INFINITY, 130 +0.0f, 131 +1.0f, 132 +2.0f, 133 +16.0f, 134 +Float.MIN_VALUE, 135 +Float_MAX_SUBNORMAL, 136 +Float.MIN_NORMAL, 137 +Float.MAX_VALUE 138 }; 139 140 int[] specialResults = {Float.MAX_EXPONENT + 1, // NaN results 141 Float.MAX_EXPONENT + 1, // Infinite results 142 Float.MIN_EXPONENT - 1, // Zero results 143 0, 144 1, 145 4, 146 Float.MIN_EXPONENT - 1, 147 -Float.MAX_EXPONENT, 148 Float.MIN_EXPONENT, 149 Float.MAX_EXPONENT 150 }; 151 152 // Special value tests 153 for (int i = 0; i < specialValues.length; i++) { 154 testGetExponentCase(specialValues[i], specialResults[i]); 155 } 156 157 // Normal exponent tests 158 for (int i = Float.MIN_EXPONENT; i <= Float.MAX_EXPONENT; i++) { 159 // Create power of two 160 float po2 = powerOfTwoF(i); 161 162 testGetExponentCase(po2, i); 163 164 // Generate some random bit patterns for the significand 165 for (int j = 0; j < 10; j++) { 166 int randSignif = rand.nextInt(); 167 float randFloat; 168 169 randFloat = Float.intBitsToFloat( // Exponent 170 (Float.floatToIntBits(po2) & 171 (~FloatConsts.SIGNIF_BIT_MASK)) | 172 // Significand 173 (randSignif & 174 FloatConsts.SIGNIF_BIT_MASK)); 175 176 testGetExponentCase(randFloat, i); 177 } 178 179 if (i > Float.MIN_EXPONENT) { 180 float po2minus = Math.nextAfter(po2, Float.NEGATIVE_INFINITY); 181 testGetExponentCase(po2minus, i - 1); 182 } 183 } 184 185 // Subnormal exponent tests 186 187 /* 188 * Start with MIN_VALUE, left shift, test high value, low 189 * values, and random in between. 190 * 191 * Use nextAfter to calculate, high value of previous binade, 192 * loop count i will indicate how many random bits, if any are 193 * needed. 194 */ 195 196 float top = Float.MIN_VALUE; 197 for (int i = 1; 198 i < FloatConsts.SIGNIFICAND_WIDTH; 199 i++, top *= 2.0f) { 200 201 testGetExponentCase(top, Float.MIN_EXPONENT - 1); 202 203 // Test largest value in next smaller binade 204 if (i >= 3) {// (i == 1) would test 0.0; 205 // (i == 2) would just retest MIN_VALUE 206 testGetExponentCase(Math.nextAfter(top, 0.0f), Float.MIN_EXPONENT - 1); 207 208 if (i >= 10) { 209 // create a bit mask with (i-1) 1's in the low order 210 // bits 211 int mask = ~((~0) << (i - 1)); 212 float randFloat = Float.intBitsToFloat( // Exponent 213 Float.floatToIntBits(top) | 214 // Significand 215 (rand.nextInt() & mask)); 216 217 testGetExponentCase(randFloat, Float.MIN_EXPONENT - 1); 218 } 219 } 220 } 221 } 222 223 @Test testDoubleGetExponent()224 public void testDoubleGetExponent() { 225 double[] specialValues = {NaNd, 226 infinityD, 227 +0.0, 228 +1.0, 229 +2.0, 230 +16.0, 231 +Double.MIN_VALUE, 232 +Double_MAX_SUBNORMAL, 233 +Double.MIN_NORMAL, 234 +Double.MAX_VALUE 235 }; 236 237 int[] specialResults = {Double.MAX_EXPONENT + 1, // NaN results 238 Double.MAX_EXPONENT + 1, // Infinite results 239 Double.MIN_EXPONENT - 1, // Zero results 240 0, 241 1, 242 4, 243 Double.MIN_EXPONENT - 1, 244 -Double.MAX_EXPONENT, 245 Double.MIN_EXPONENT, 246 Double.MAX_EXPONENT 247 }; 248 249 // Special value tests 250 for (int i = 0; i < specialValues.length; i++) { 251 testGetExponentCase(specialValues[i], specialResults[i]); 252 } 253 254 // Normal exponent tests 255 for (int i = Double.MIN_EXPONENT; i <= Double.MAX_EXPONENT; i++) { 256 // Create power of two 257 double po2 = powerOfTwoD(i); 258 259 testGetExponentCase(po2, i); 260 261 // Generate some random bit patterns for the significand 262 for (int j = 0; j < 10; j++) { 263 long randSignif = rand.nextLong(); 264 double randFloat; 265 266 randFloat = Double.longBitsToDouble( // Exponent 267 (Double.doubleToLongBits(po2) & 268 (~DoubleConsts.SIGNIF_BIT_MASK)) | 269 // Significand 270 (randSignif & 271 DoubleConsts.SIGNIF_BIT_MASK)); 272 273 testGetExponentCase(randFloat, i); 274 } 275 276 if (i > Double.MIN_EXPONENT) { 277 double po2minus = Math.nextAfter(po2, 278 Double.NEGATIVE_INFINITY); 279 testGetExponentCase(po2minus, i - 1); 280 } 281 } 282 283 // Subnormal exponent tests 284 285 /* 286 * Start with MIN_VALUE, left shift, test high value, low 287 * values, and random in between. 288 * 289 * Use nextAfter to calculate, high value of previous binade; 290 * loop count i will indicate how many random bits, if any are 291 * needed. 292 */ 293 294 double top = Double.MIN_VALUE; 295 for (int i = 1; 296 i < DoubleConsts.SIGNIFICAND_WIDTH; 297 i++, top *= 2.0f) { 298 299 testGetExponentCase(top, 300 Double.MIN_EXPONENT - 1); 301 302 // Test largest value in next smaller binade 303 if (i >= 3) {// (i == 1) would test 0.0; 304 // (i == 2) would just retest MIN_VALUE 305 testGetExponentCase(Math.nextAfter(top, 0.0), 306 Double.MIN_EXPONENT - 1); 307 308 if (i >= 10) { 309 // create a bit mask with (i-1) 1's in the low order 310 // bits 311 long mask = ~((~0L) << (i - 1)); 312 double randFloat = Double.longBitsToDouble( // Exponent 313 Double.doubleToLongBits(top) | 314 // Significand 315 (rand.nextLong() & mask)); 316 317 testGetExponentCase(randFloat, 318 Double.MIN_EXPONENT - 1); 319 } 320 } 321 } 322 } 323 324 325 /* ******************** nextAfter tests ****************************** */ 326 testNextAfterCase(float start, double direction, float expected)327 static void testNextAfterCase(float start, double direction, float expected) { 328 float minus_start = -start; 329 double minus_direction = -direction; 330 float minus_expected = -expected; 331 332 Tests.test("Math.nextAfter(float,double)", start, direction, 333 Math.nextAfter(start, direction), expected); 334 Tests.test("Math.nextAfter(float,double)", minus_start, minus_direction, 335 Math.nextAfter(minus_start, minus_direction), minus_expected); 336 337 Tests.test("StrictMath.nextAfter(float,double)", start, direction, 338 StrictMath.nextAfter(start, direction), expected); 339 Tests.test("StrictMath.nextAfter(float,double)", minus_start, minus_direction, 340 StrictMath.nextAfter(minus_start, minus_direction), minus_expected); 341 } 342 testNextAfterCase(double start, double direction, double expected)343 static void testNextAfterCase(double start, double direction, double expected) { 344 double minus_start = -start; 345 double minus_direction = -direction; 346 double minus_expected = -expected; 347 348 Tests.test("Math.nextAfter(double,double)", start, direction, 349 Math.nextAfter(start, direction), expected); 350 Tests.test("Math.nextAfter(double,double)", minus_start, minus_direction, 351 Math.nextAfter(minus_start, minus_direction), minus_expected); 352 353 Tests.test("StrictMath.nextAfter(double,double)", start, direction, 354 StrictMath.nextAfter(start, direction), expected); 355 Tests.test("StrictMath.nextAfter(double,double)", minus_start, minus_direction, 356 StrictMath.nextAfter(minus_start, minus_direction), minus_expected); 357 } 358 359 @Test testFloatNextAfter()360 public void testFloatNextAfter() { 361 /* 362 * Each row of the testCases matrix represents one test case 363 * for nexAfter; given the input of the first two columns, the 364 * result in the last column is expected. 365 */ 366 float[][] testCases = { 367 {NaNf, NaNf, NaNf}, 368 {NaNf, 0.0f, NaNf}, 369 {0.0f, NaNf, NaNf}, 370 {NaNf, infinityF, NaNf}, 371 {infinityF, NaNf, NaNf}, 372 373 {infinityF, infinityF, infinityF}, 374 {infinityF, -infinityF, Float.MAX_VALUE}, 375 {infinityF, 0.0f, Float.MAX_VALUE}, 376 377 {Float.MAX_VALUE, infinityF, infinityF}, 378 {Float.MAX_VALUE, -infinityF, Float_MAX_VALUEmm}, 379 {Float.MAX_VALUE, Float.MAX_VALUE, Float.MAX_VALUE}, 380 {Float.MAX_VALUE, 0.0f, Float_MAX_VALUEmm}, 381 382 {Float_MAX_VALUEmm, Float.MAX_VALUE, Float.MAX_VALUE}, 383 {Float_MAX_VALUEmm, infinityF, Float.MAX_VALUE}, 384 {Float_MAX_VALUEmm, Float_MAX_VALUEmm, Float_MAX_VALUEmm}, 385 386 {Float.MIN_NORMAL, infinityF, Float.MIN_NORMAL + 387 Float.MIN_VALUE}, 388 {Float.MIN_NORMAL, -infinityF, Float_MAX_SUBNORMAL}, 389 {Float.MIN_NORMAL, 1.0f, Float.MIN_NORMAL + 390 Float.MIN_VALUE}, 391 {Float.MIN_NORMAL, -1.0f, Float_MAX_SUBNORMAL}, 392 {Float.MIN_NORMAL, Float.MIN_NORMAL, Float.MIN_NORMAL}, 393 394 {Float_MAX_SUBNORMAL, Float.MIN_NORMAL, Float.MIN_NORMAL}, 395 {Float_MAX_SUBNORMAL, Float_MAX_SUBNORMAL, Float_MAX_SUBNORMAL}, 396 {Float_MAX_SUBNORMAL, 0.0f, Float_MAX_SUBNORMALmm}, 397 398 {Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMAL, Float_MAX_SUBNORMAL}, 399 {Float_MAX_SUBNORMALmm, 0.0f, Float_MAX_SUBNORMALmm - Float.MIN_VALUE}, 400 {Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMALmm}, 401 402 {Float.MIN_VALUE, 0.0f, 0.0f}, 403 {-Float.MIN_VALUE, 0.0f, -0.0f}, 404 {Float.MIN_VALUE, Float.MIN_VALUE, Float.MIN_VALUE}, 405 {Float.MIN_VALUE, 1.0f, 2 * Float.MIN_VALUE}, 406 407 // Make sure zero behavior is tested 408 {0.0f, 0.0f, 0.0f}, 409 {0.0f, -0.0f, -0.0f}, 410 {-0.0f, 0.0f, 0.0f}, 411 {-0.0f, -0.0f, -0.0f}, 412 {0.0f, infinityF, Float.MIN_VALUE}, 413 {0.0f, -infinityF, -Float.MIN_VALUE}, 414 {-0.0f, infinityF, Float.MIN_VALUE}, 415 {-0.0f, -infinityF, -Float.MIN_VALUE}, 416 {0.0f, Float.MIN_VALUE, Float.MIN_VALUE}, 417 {0.0f, -Float.MIN_VALUE, -Float.MIN_VALUE}, 418 {-0.0f, Float.MIN_VALUE, Float.MIN_VALUE}, 419 {-0.0f, -Float.MIN_VALUE, -Float.MIN_VALUE} 420 }; 421 422 for (float[] testCase : testCases) { 423 testNextAfterCase(testCase[0], testCase[1], testCase[2]); 424 } 425 } 426 427 @Test testDoubleNextAfter()428 public void testDoubleNextAfter() { 429 /* 430 * Each row of the testCases matrix represents one test case 431 * for nexAfter; given the input of the first two columns, the 432 * result in the last column is expected. 433 */ 434 double[][] testCases = { 435 {NaNd, NaNd, NaNd}, 436 {NaNd, 0.0d, NaNd}, 437 {0.0d, NaNd, NaNd}, 438 {NaNd, infinityD, NaNd}, 439 {infinityD, NaNd, NaNd}, 440 441 {infinityD, infinityD, infinityD}, 442 {infinityD, -infinityD, Double.MAX_VALUE}, 443 {infinityD, 0.0d, Double.MAX_VALUE}, 444 445 {Double.MAX_VALUE, infinityD, infinityD}, 446 {Double.MAX_VALUE, -infinityD, Double_MAX_VALUEmm}, 447 {Double.MAX_VALUE, Double.MAX_VALUE, Double.MAX_VALUE}, 448 {Double.MAX_VALUE, 0.0d, Double_MAX_VALUEmm}, 449 450 {Double_MAX_VALUEmm, Double.MAX_VALUE, Double.MAX_VALUE}, 451 {Double_MAX_VALUEmm, infinityD, Double.MAX_VALUE}, 452 {Double_MAX_VALUEmm, Double_MAX_VALUEmm, Double_MAX_VALUEmm}, 453 454 {Double.MIN_NORMAL, infinityD, Double.MIN_NORMAL + 455 Double.MIN_VALUE}, 456 {Double.MIN_NORMAL, -infinityD, Double_MAX_SUBNORMAL}, 457 {Double.MIN_NORMAL, 1.0f, Double.MIN_NORMAL + 458 Double.MIN_VALUE}, 459 {Double.MIN_NORMAL, -1.0f, Double_MAX_SUBNORMAL}, 460 {Double.MIN_NORMAL, Double.MIN_NORMAL, Double.MIN_NORMAL}, 461 462 {Double_MAX_SUBNORMAL, Double.MIN_NORMAL, Double.MIN_NORMAL}, 463 {Double_MAX_SUBNORMAL, Double_MAX_SUBNORMAL, Double_MAX_SUBNORMAL}, 464 {Double_MAX_SUBNORMAL, 0.0d, Double_MAX_SUBNORMALmm}, 465 466 {Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMAL, Double_MAX_SUBNORMAL}, 467 {Double_MAX_SUBNORMALmm, 0.0d, Double_MAX_SUBNORMALmm - Double.MIN_VALUE}, 468 {Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMALmm}, 469 470 {Double.MIN_VALUE, 0.0d, 0.0d}, 471 {-Double.MIN_VALUE, 0.0d, -0.0d}, 472 {Double.MIN_VALUE, Double.MIN_VALUE, Double.MIN_VALUE}, 473 {Double.MIN_VALUE, 1.0f, 2 * Double.MIN_VALUE}, 474 475 // Make sure zero behavior is tested 476 {0.0d, 0.0d, 0.0d}, 477 {0.0d, -0.0d, -0.0d}, 478 {-0.0d, 0.0d, 0.0d}, 479 {-0.0d, -0.0d, -0.0d}, 480 {0.0d, infinityD, Double.MIN_VALUE}, 481 {0.0d, -infinityD, -Double.MIN_VALUE}, 482 {-0.0d, infinityD, Double.MIN_VALUE}, 483 {-0.0d, -infinityD, -Double.MIN_VALUE}, 484 {0.0d, Double.MIN_VALUE, Double.MIN_VALUE}, 485 {0.0d, -Double.MIN_VALUE, -Double.MIN_VALUE}, 486 {-0.0d, Double.MIN_VALUE, Double.MIN_VALUE}, 487 {-0.0d, -Double.MIN_VALUE, -Double.MIN_VALUE} 488 }; 489 490 for (double[] testCase : testCases) { 491 testNextAfterCase(testCase[0], testCase[1], testCase[2]); 492 } 493 } 494 495 /* ******************** nextUp tests ********************************* */ 496 497 @Test testFloatNextUp()498 public void testFloatNextUp() { 499 /* 500 * Each row of testCases represents one test case for nextUp; 501 * the first column is the input and the second column is the 502 * expected result. 503 */ 504 float[][] testCases = { 505 {NaNf, NaNf}, 506 {-infinityF, -Float.MAX_VALUE}, 507 {-Float.MAX_VALUE, -Float_MAX_VALUEmm}, 508 {-Float.MIN_NORMAL, -Float_MAX_SUBNORMAL}, 509 {-Float_MAX_SUBNORMAL, -Float_MAX_SUBNORMALmm}, 510 {-Float.MIN_VALUE, -0.0f}, 511 {-0.0f, Float.MIN_VALUE}, 512 {+0.0f, Float.MIN_VALUE}, 513 {Float.MIN_VALUE, Float.MIN_VALUE * 2}, 514 {Float_MAX_SUBNORMALmm, Float_MAX_SUBNORMAL}, 515 {Float_MAX_SUBNORMAL, Float.MIN_NORMAL}, 516 {Float.MIN_NORMAL, Float.MIN_NORMAL + Float.MIN_VALUE}, 517 {Float_MAX_VALUEmm, Float.MAX_VALUE}, 518 {Float.MAX_VALUE, infinityF}, 519 {infinityF, infinityF} 520 }; 521 522 for (float[] testCase : testCases) { 523 Tests.test("Math.nextUp(float)", 524 testCase[0], Math.nextUp(testCase[0]), testCase[1]); 525 526 Tests.test("StrictMath.nextUp(float)", 527 testCase[0], StrictMath.nextUp(testCase[0]), testCase[1]); 528 } 529 } 530 531 @Test testDoubleNextUp()532 public void testDoubleNextUp() { 533 /* 534 * Each row of testCases represents one test case for nextUp; 535 * the first column is the input and the second column is the 536 * expected result. 537 */ 538 double[][] testCases = { 539 {NaNd, NaNd}, 540 {-infinityD, -Double.MAX_VALUE}, 541 {-Double.MAX_VALUE, -Double_MAX_VALUEmm}, 542 {-Double.MIN_NORMAL, -Double_MAX_SUBNORMAL}, 543 {-Double_MAX_SUBNORMAL, -Double_MAX_SUBNORMALmm}, 544 {-Double.MIN_VALUE, -0.0d}, 545 {-0.0d, Double.MIN_VALUE}, 546 {+0.0d, Double.MIN_VALUE}, 547 {Double.MIN_VALUE, Double.MIN_VALUE * 2}, 548 {Double_MAX_SUBNORMALmm, Double_MAX_SUBNORMAL}, 549 {Double_MAX_SUBNORMAL, Double.MIN_NORMAL}, 550 {Double.MIN_NORMAL, Double.MIN_NORMAL + Double.MIN_VALUE}, 551 {Double_MAX_VALUEmm, Double.MAX_VALUE}, 552 {Double.MAX_VALUE, infinityD}, 553 {infinityD, infinityD} 554 }; 555 556 for (double[] testCase : testCases) { 557 Tests.test("Math.nextUp(double)", 558 testCase[0], Math.nextUp(testCase[0]), testCase[1]); 559 560 Tests.test("StrictMath.nextUp(double)", 561 testCase[0], StrictMath.nextUp(testCase[0]), testCase[1]); 562 } 563 } 564 565 /* ******************** nextDown tests ********************************* */ 566 567 @Test testFloatNextDown()568 public void testFloatNextDown() { 569 /* 570 * Each row of testCases represents one test case for nextDown; 571 * the first column is the input and the second column is the 572 * expected result. 573 */ 574 float[][] testCases = { 575 {NaNf, NaNf}, 576 {-infinityF, -infinityF}, 577 {-Float.MAX_VALUE, -infinityF}, 578 {-Float_MAX_VALUEmm, -Float.MAX_VALUE}, 579 {-Float_MAX_SUBNORMAL, -Float.MIN_NORMAL}, 580 {-Float_MAX_SUBNORMALmm, -Float_MAX_SUBNORMAL}, 581 {-0.0f, -Float.MIN_VALUE}, 582 {+0.0f, -Float.MIN_VALUE}, 583 {Float.MIN_VALUE, 0.0f}, 584 {Float.MIN_VALUE * 2, Float.MIN_VALUE}, 585 {Float_MAX_SUBNORMAL, Float_MAX_SUBNORMALmm}, 586 {Float.MIN_NORMAL, Float_MAX_SUBNORMAL}, 587 {Float.MIN_NORMAL + 588 Float.MIN_VALUE, Float.MIN_NORMAL}, 589 {Float.MAX_VALUE, Float_MAX_VALUEmm}, 590 {infinityF, Float.MAX_VALUE}, 591 }; 592 593 for (float[] testCase : testCases) { 594 Tests.test("Math.nextDown(float)", 595 testCase[0], Math.nextDown(testCase[0]), testCase[1]); 596 597 Tests.test("StrictMath.nextDown(float)", 598 testCase[0], StrictMath.nextDown(testCase[0]), testCase[1]); 599 } 600 } 601 602 @Test testDoubleNextDown()603 public void testDoubleNextDown() { 604 /* 605 * Each row of testCases represents one test case for nextDown; 606 * the first column is the input and the second column is the 607 * expected result. 608 */ 609 double[][] testCases = { 610 {NaNd, NaNd}, 611 {-infinityD, -infinityD}, 612 {-Double.MAX_VALUE, -infinityD}, 613 {-Double_MAX_VALUEmm, -Double.MAX_VALUE}, 614 {-Double_MAX_SUBNORMAL, -Double.MIN_NORMAL}, 615 {-Double_MAX_SUBNORMALmm, -Double_MAX_SUBNORMAL}, 616 {-0.0d, -Double.MIN_VALUE}, 617 {+0.0d, -Double.MIN_VALUE}, 618 {Double.MIN_VALUE, 0.0d}, 619 {Double.MIN_VALUE * 2, Double.MIN_VALUE}, 620 {Double_MAX_SUBNORMAL, Double_MAX_SUBNORMALmm}, 621 {Double.MIN_NORMAL, Double_MAX_SUBNORMAL}, 622 {Double.MIN_NORMAL + 623 Double.MIN_VALUE, Double.MIN_NORMAL}, 624 {Double.MAX_VALUE, Double_MAX_VALUEmm}, 625 {infinityD, Double.MAX_VALUE}, 626 }; 627 628 for (double[] testCase : testCases) { 629 Tests.test("Math.nextDown(double)", 630 testCase[0], Math.nextDown(testCase[0]), testCase[1]); 631 632 Tests.test("StrictMath.nextDown(double)", 633 testCase[0], StrictMath.nextDown(testCase[0]), testCase[1]); 634 } 635 } 636 637 638 /* ********************** boolean tests ****************************** */ 639 640 /* 641 * Combined tests for boolean functions, isFinite, isInfinite, 642 * isNaN, isUnordered. 643 */ 644 @Test testFloatBooleanMethods()645 public void testFloatBooleanMethods() { 646 float[] testCases = { 647 NaNf, 648 -infinityF, 649 infinityF, 650 -Float.MAX_VALUE, 651 -3.0f, 652 -1.0f, 653 -Float.MIN_NORMAL, 654 -Float_MAX_SUBNORMALmm, 655 -Float_MAX_SUBNORMAL, 656 -Float.MIN_VALUE, 657 -0.0f, 658 +0.0f, 659 Float.MIN_VALUE, 660 Float_MAX_SUBNORMALmm, 661 Float_MAX_SUBNORMAL, 662 Float.MIN_NORMAL, 663 1.0f, 664 3.0f, 665 Float_MAX_VALUEmm, 666 Float.MAX_VALUE 667 }; 668 669 for (int i = 0; i < testCases.length; i++) { 670 // isNaN 671 Tests.test("Float.isNaN(float)", testCases[i], 672 Float.isNaN(testCases[i]), (i == 0)); 673 674 // isFinite 675 Tests.test("Float.isFinite(float)", testCases[i], 676 Float.isFinite(testCases[i]), (i >= 3)); 677 678 // isInfinite 679 Tests.test("Float.isInfinite(float)", testCases[i], 680 Float.isInfinite(testCases[i]), (i == 1 || i == 2)); 681 682 // isUnorderd 683 for (int j = 0; j < testCases.length; j++) { 684 Tests.test("Tests.isUnordered(float, float)", testCases[i], testCases[j], 685 Tests.isUnordered(testCases[i], testCases[j]), (i == 0 || j == 0)); 686 } 687 } 688 } 689 690 @Test testDoubleBooleanMethods()691 public void testDoubleBooleanMethods() { 692 double[] testCases = { 693 NaNd, 694 -infinityD, 695 infinityD, 696 -Double.MAX_VALUE, 697 -3.0d, 698 -1.0d, 699 -Double.MIN_NORMAL, 700 -Double_MAX_SUBNORMALmm, 701 -Double_MAX_SUBNORMAL, 702 -Double.MIN_VALUE, 703 -0.0d, 704 +0.0d, 705 Double.MIN_VALUE, 706 Double_MAX_SUBNORMALmm, 707 Double_MAX_SUBNORMAL, 708 Double.MIN_NORMAL, 709 1.0d, 710 3.0d, 711 Double_MAX_VALUEmm, 712 Double.MAX_VALUE 713 }; 714 715 for (int i = 0; i < testCases.length; i++) { 716 // isNaN 717 Tests.test("Double.isNaN(double)", testCases[i], 718 Double.isNaN(testCases[i]), (i == 0)); 719 720 // isFinite 721 Tests.test("Double.isFinite(double)", testCases[i], 722 Double.isFinite(testCases[i]), (i >= 3)); 723 724 // isInfinite 725 Tests.test("Double.isInfinite(double)", testCases[i], 726 Double.isInfinite(testCases[i]), (i == 1 || i == 2)); 727 728 // isUnorderd 729 for (int j = 0; j < testCases.length; j++) { 730 Tests.test("Tests.isUnordered(double, double)", testCases[i], testCases[j], 731 Tests.isUnordered(testCases[i], testCases[j]), (i == 0 || j == 0)); 732 } 733 } 734 } 735 736 /* ******************** copySign tests******************************** */ 737 @Test testFloatCopySign()738 public void testFloatCopySign() { 739 // testCases[0] are logically positive numbers; 740 // testCases[1] are negative numbers. 741 float[][] testCases = { 742 {+0.0f, 743 Float.MIN_VALUE, 744 Float_MAX_SUBNORMALmm, 745 Float_MAX_SUBNORMAL, 746 Float.MIN_NORMAL, 747 1.0f, 748 3.0f, 749 Float_MAX_VALUEmm, 750 Float.MAX_VALUE, 751 infinityF, 752 }, 753 {-infinityF, 754 -Float.MAX_VALUE, 755 -3.0f, 756 -1.0f, 757 -Float.MIN_NORMAL, 758 -Float_MAX_SUBNORMALmm, 759 -Float_MAX_SUBNORMAL, 760 -Float.MIN_VALUE, 761 -0.0f} 762 }; 763 764 float[] NaNs = {Float.intBitsToFloat(0x7fc00000), // "positive" NaN 765 Float.intBitsToFloat(0xFfc00000)}; // "negative" NaN 766 767 // Tests shared between raw and non-raw versions 768 for (int i = 0; i < 2; i++) { 769 for (int j = 0; j < 2; j++) { 770 for (int m = 0; m < testCases[i].length; m++) { 771 for (int n = 0; n < testCases[j].length; n++) { 772 // copySign(magnitude, sign) 773 Tests.test("Math.copySign(float,float)", 774 testCases[i][m], testCases[j][n], 775 Math.copySign(testCases[i][m], testCases[j][n]), 776 (j == 0 ? 1.0f : -1.0f) * Math.abs(testCases[i][m])); 777 778 Tests.test("StrictMath.copySign(float,float)", 779 testCases[i][m], testCases[j][n], 780 StrictMath.copySign(testCases[i][m], testCases[j][n]), 781 (j == 0 ? 1.0f : -1.0f) * Math.abs(testCases[i][m])); 782 } 783 } 784 } 785 } 786 787 // For rawCopySign, NaN may effectively have either sign bit 788 // while for copySign NaNs are treated as if they always have 789 // a zero sign bit (i.e. as positive numbers) 790 for (int i = 0; i < 2; i++) { 791 for (float naN : NaNs) { 792 for (int m = 0; m < testCases[i].length; m++) { 793 Tests.test("StrictMath.copySign(float,float)", 794 testCases[i][m], naN, 795 StrictMath.copySign(testCases[i][m], naN), 796 Math.abs(testCases[i][m])); 797 } 798 } 799 } 800 } 801 802 @Test testDoubleCopySign()803 public void testDoubleCopySign() { 804 // testCases[0] are logically positive numbers; 805 // testCases[1] are negative numbers. 806 double[][] testCases = { 807 {+0.0d, 808 Double.MIN_VALUE, 809 Double_MAX_SUBNORMALmm, 810 Double_MAX_SUBNORMAL, 811 Double.MIN_NORMAL, 812 1.0d, 813 3.0d, 814 Double_MAX_VALUEmm, 815 Double.MAX_VALUE, 816 infinityD, 817 }, 818 {-infinityD, 819 -Double.MAX_VALUE, 820 -3.0d, 821 -1.0d, 822 -Double.MIN_NORMAL, 823 -Double_MAX_SUBNORMALmm, 824 -Double_MAX_SUBNORMAL, 825 -Double.MIN_VALUE, 826 -0.0d} 827 }; 828 829 double[] NaNs = {Double.longBitsToDouble(0x7ff8000000000000L), // "positive" NaN 830 Double.longBitsToDouble(0xfff8000000000000L), // "negative" NaN 831 Double.longBitsToDouble(0x7FF0000000000001L), 832 Double.longBitsToDouble(0xFFF0000000000001L), 833 Double.longBitsToDouble(0x7FF8555555555555L), 834 Double.longBitsToDouble(0xFFF8555555555555L), 835 Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL), 836 Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL), 837 Double.longBitsToDouble(0x7FFDeadBeef00000L), 838 Double.longBitsToDouble(0xFFFDeadBeef00000L), 839 Double.longBitsToDouble(0x7FFCafeBabe00000L), 840 Double.longBitsToDouble(0xFFFCafeBabe00000L)}; 841 842 // Tests shared between Math and StrictMath versions 843 for (int i = 0; i < 2; i++) { 844 for (int j = 0; j < 2; j++) { 845 for (int m = 0; m < testCases[i].length; m++) { 846 for (int n = 0; n < testCases[j].length; n++) { 847 // copySign(magnitude, sign) 848 Tests.test("Math.copySign(double,double)", 849 testCases[i][m], testCases[j][n], 850 Math.copySign(testCases[i][m], testCases[j][n]), 851 (j == 0 ? 1.0f : -1.0f) * Math.abs(testCases[i][m])); 852 853 Tests.test("StrictMath.copySign(double,double)", 854 testCases[i][m], testCases[j][n], 855 StrictMath.copySign(testCases[i][m], testCases[j][n]), 856 (j == 0 ? 1.0f : -1.0f) * Math.abs(testCases[i][m])); 857 } 858 } 859 } 860 } 861 862 // For Math.copySign, NaN may effectively have either sign bit 863 // while for StrictMath.copySign NaNs are treated as if they 864 // always have a zero sign bit (i.e. as positive numbers) 865 for (int i = 0; i < 2; i++) { 866 for (double naN : NaNs) { 867 for (int m = 0; m < testCases[i].length; m++) { 868 Tests.test("StrictMath.copySign(double,double)", 869 testCases[i][m], naN, 870 StrictMath.copySign(testCases[i][m], naN), 871 Math.abs(testCases[i][m])); 872 } 873 } 874 } 875 } 876 877 /* ************************ scalb tests ******************************* */ 878 testScalbCase(float value, int scale_factor, float expected)879 static void testScalbCase(float value, int scale_factor, float expected) { 880 Tests.test("Math.scalb(float,int)", 881 value, scale_factor, 882 Math.scalb(value, scale_factor), expected); 883 884 Tests.test("Math.scalb(float,int)", 885 -value, scale_factor, 886 Math.scalb(-value, scale_factor), -expected); 887 888 Tests.test("StrictMath.scalb(float,int)", 889 value, scale_factor, 890 StrictMath.scalb(value, scale_factor), expected); 891 892 Tests.test("StrictMath.scalb(float,int)", 893 -value, scale_factor, 894 StrictMath.scalb(-value, scale_factor), -expected); 895 } 896 897 @Test testFloatScalb()898 public void testFloatScalb() { 899 int MAX_SCALE = Float.MAX_EXPONENT + -Float.MIN_EXPONENT + 900 FloatConsts.SIGNIFICAND_WIDTH + 1; 901 902 // Arguments x, where scalb(x,n) is x for any n. 903 float[] identityTestCases = {NaNf, 904 -0.0f, 905 +0.0f, 906 infinityF, 907 -infinityF 908 }; 909 910 float[] subnormalTestCases = { 911 Float.MIN_VALUE, 912 3.0f * Float.MIN_VALUE, 913 Float_MAX_SUBNORMALmm, 914 Float_MAX_SUBNORMAL 915 }; 916 917 float[] someTestCases = { 918 Float.MIN_VALUE, 919 3.0f * Float.MIN_VALUE, 920 Float_MAX_SUBNORMALmm, 921 Float_MAX_SUBNORMAL, 922 Float.MIN_NORMAL, 923 1.0f, 924 2.0f, 925 3.0f, 926 (float) Math.PI, 927 Float_MAX_VALUEmm, 928 Float.MAX_VALUE 929 }; 930 931 int[] oneMultiplyScalingFactors = { 932 Float.MIN_EXPONENT, 933 Float.MIN_EXPONENT + 1, 934 -3, 935 -2, 936 -1, 937 0, 938 1, 939 2, 940 3, 941 Float.MAX_EXPONENT - 1, 942 Float.MAX_EXPONENT 943 }; 944 945 int[] manyScalingFactors = { 946 Integer.MIN_VALUE, 947 Integer.MIN_VALUE + 1, 948 -MAX_SCALE - 1, 949 -MAX_SCALE, 950 -MAX_SCALE + 1, 951 952 2 * Float.MIN_EXPONENT - 1, // -253 953 2 * Float.MIN_EXPONENT, // -252 954 2 * Float.MIN_EXPONENT + 1, // -251 955 956 Float.MIN_EXPONENT - FloatConsts.SIGNIFICAND_WIDTH, 957 FloatConsts.MIN_SUB_EXPONENT, 958 -Float.MAX_EXPONENT, // -127 959 Float.MIN_EXPONENT, // -126 960 961 -2, 962 -1, 963 0, 964 1, 965 2, 966 967 Float.MAX_EXPONENT - 1, // 126 968 Float.MAX_EXPONENT, // 127 969 Float.MAX_EXPONENT + 1, // 128 970 971 2 * Float.MAX_EXPONENT - 1, // 253 972 2 * Float.MAX_EXPONENT, // 254 973 2 * Float.MAX_EXPONENT + 1, // 255 974 975 MAX_SCALE - 1, 976 MAX_SCALE, 977 MAX_SCALE + 1, 978 Integer.MAX_VALUE - 1, 979 Integer.MAX_VALUE 980 }; 981 982 // Test cases where scaling is always a no-op 983 for (float identityTestCase : identityTestCases) { 984 for (int manyScalingFactor : manyScalingFactors) { 985 testScalbCase(identityTestCase, manyScalingFactor, identityTestCase); 986 } 987 } 988 989 // Test cases where result is 0.0 or infinity due to magnitude 990 // of the scaling factor 991 for (float someTestCase : someTestCases) { 992 for (int scaleFactor : manyScalingFactors) { 993 if (Math.abs(scaleFactor) >= MAX_SCALE) { 994 testScalbCase(someTestCase, 995 scaleFactor, 996 Math.copySign((scaleFactor > 0 ? infinityF : 0.0f), someTestCase)); 997 } 998 } 999 } 1000 1001 // Test cases that could be done with one floating-point 1002 // multiply. 1003 for (float someTestCase : someTestCases) { 1004 for (int scaleFactor : oneMultiplyScalingFactors) { 1005 testScalbCase(someTestCase, 1006 scaleFactor, 1007 someTestCase * powerOfTwoF(scaleFactor)); 1008 } 1009 } 1010 1011 // Create 2^MAX_EXPONENT 1012 float twoToTheMaxExp = 1.0f; // 2^0 1013 for (int i = 0; i < Float.MAX_EXPONENT; i++) { 1014 twoToTheMaxExp *= 2.0f; 1015 } 1016 1017 // Scale-up subnormal values until they all overflow 1018 for (float subnormalTestCase : subnormalTestCases) { 1019 float scale = 1.0f; // 2^j 1020 1021 for (int scaleFactor = Float.MAX_EXPONENT * 2; scaleFactor < MAX_SCALE; 1022 scaleFactor++) {// MAX_SCALE -1 should cause overflow 1023 1024 testScalbCase(subnormalTestCase, 1025 scaleFactor, 1026 (Tests.ilogb(subnormalTestCase) + scaleFactor > Float.MAX_EXPONENT) ? 1027 Math.copySign(infinityF, subnormalTestCase) : // overflow 1028 // calculate right answer 1029 twoToTheMaxExp * (twoToTheMaxExp * (scale * subnormalTestCase))); 1030 scale *= 2.0f; 1031 } 1032 } 1033 1034 // Scale down a large number until it underflows. By scaling 1035 // down MAX_NORMALmm, the first subnormal result will be exact 1036 // but the next one will round -- all those results can be 1037 // checked by halving a separate value in the loop. Actually, 1038 // we can keep halving and checking until the product is zero 1039 // since: 1040 // 1041 // 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact 1042 // it will round *up* 1043 // 1044 // 2. When rounding first occurs in the expected product, it 1045 // too rounds up, to 2^-MAX_EXPONENT. 1046 // 1047 // Halving expected after rounding happends to give the same 1048 // result as the scalb operation. 1049 float expected = Float_MAX_VALUEmm * 0.5f; 1050 for (int i = -1; i > -MAX_SCALE; i--) { 1051 testScalbCase(Float_MAX_VALUEmm, i, expected); 1052 1053 expected *= 0.5f; 1054 } 1055 1056 // Tricky rounding tests: 1057 // Scale down a large number into subnormal range such that if 1058 // scalb is being implemented with multiple floating-point 1059 // multiplies, the value would round twice if the multiplies 1060 // were done in the wrong order. 1061 1062 float value = 0x8.0000bP-5f; 1063 expected = 0x1.00001p-129f; 1064 1065 for (int i = 0; i < 129; i++) { 1066 testScalbCase(value, 1067 -127 - i, 1068 expected); 1069 value *= 2.0f; 1070 } 1071 } 1072 testScalbCase(double value, int scale_factor, double expected)1073 static void testScalbCase(double value, int scale_factor, double expected) { 1074 Tests.test("Math.scalb(double,int)", 1075 value, scale_factor, 1076 Math.scalb(value, scale_factor), expected); 1077 1078 Tests.test("Math.scalb(double,int)", 1079 -value, scale_factor, 1080 Math.scalb(-value, scale_factor), -expected); 1081 1082 Tests.test("StrictMath.scalb(double,int)", 1083 value, scale_factor, 1084 StrictMath.scalb(value, scale_factor), expected); 1085 1086 Tests.test("StrictMath.scalb(double,int)", 1087 -value, scale_factor, 1088 StrictMath.scalb(-value, scale_factor), -expected); 1089 } 1090 1091 @Test testDoubleScalb()1092 public void testDoubleScalb() { 1093 int MAX_SCALE = Double.MAX_EXPONENT + -Double.MIN_EXPONENT + 1094 DoubleConsts.SIGNIFICAND_WIDTH + 1; 1095 1096 // Arguments x, where scalb(x,n) is x for any n. 1097 double[] identityTestCases = {NaNd, 1098 -0.0, 1099 +0.0, 1100 infinityD, 1101 }; 1102 1103 double[] subnormalTestCases = { 1104 Double.MIN_VALUE, 1105 3.0d * Double.MIN_VALUE, 1106 Double_MAX_SUBNORMALmm, 1107 Double_MAX_SUBNORMAL 1108 }; 1109 1110 double[] someTestCases = { 1111 Double.MIN_VALUE, 1112 3.0d * Double.MIN_VALUE, 1113 Double_MAX_SUBNORMALmm, 1114 Double_MAX_SUBNORMAL, 1115 Double.MIN_NORMAL, 1116 1.0d, 1117 2.0d, 1118 3.0d, 1119 Math.PI, 1120 Double_MAX_VALUEmm, 1121 Double.MAX_VALUE 1122 }; 1123 1124 int[] oneMultiplyScalingFactors = { 1125 Double.MIN_EXPONENT, 1126 Double.MIN_EXPONENT + 1, 1127 -3, 1128 -2, 1129 -1, 1130 0, 1131 1, 1132 2, 1133 3, 1134 Double.MAX_EXPONENT - 1, 1135 Double.MAX_EXPONENT 1136 }; 1137 1138 int[] manyScalingFactors = { 1139 Integer.MIN_VALUE, 1140 Integer.MIN_VALUE + 1, 1141 -MAX_SCALE - 1, 1142 -MAX_SCALE, 1143 -MAX_SCALE + 1, 1144 1145 2 * Double.MIN_EXPONENT - 1, // -2045 1146 2 * Double.MIN_EXPONENT, // -2044 1147 2 * Double.MIN_EXPONENT + 1, // -2043 1148 1149 Double.MIN_EXPONENT, // -1022 1150 Double.MIN_EXPONENT - DoubleConsts.SIGNIFICAND_WIDTH, 1151 DoubleConsts.MIN_SUB_EXPONENT, 1152 -Double.MAX_EXPONENT, // -1023 1153 Double.MIN_EXPONENT, // -1022 1154 1155 -2, 1156 -1, 1157 0, 1158 1, 1159 2, 1160 1161 Double.MAX_EXPONENT - 1, // 1022 1162 Double.MAX_EXPONENT, // 1023 1163 Double.MAX_EXPONENT + 1, // 1024 1164 1165 2 * Double.MAX_EXPONENT - 1, // 2045 1166 2 * Double.MAX_EXPONENT, // 2046 1167 2 * Double.MAX_EXPONENT + 1, // 2047 1168 1169 MAX_SCALE - 1, 1170 MAX_SCALE, 1171 MAX_SCALE + 1, 1172 Integer.MAX_VALUE - 1, 1173 Integer.MAX_VALUE 1174 }; 1175 1176 // Test cases where scaling is always a no-op 1177 for (double identityTestCase : identityTestCases) { 1178 for (int manyScalingFactor : manyScalingFactors) { 1179 testScalbCase(identityTestCase, 1180 manyScalingFactor, 1181 identityTestCase); 1182 } 1183 } 1184 1185 // Test cases where result is 0.0 or infinity due to magnitude 1186 // of the scaling factor 1187 for (double someTestCase : someTestCases) { 1188 for (int scaleFactor : manyScalingFactors) { 1189 if (Math.abs(scaleFactor) >= MAX_SCALE) { 1190 testScalbCase(someTestCase, 1191 scaleFactor, 1192 Math.copySign((scaleFactor > 0 ? infinityD : 0.0), someTestCase)); 1193 } 1194 } 1195 } 1196 1197 // Test cases that could be done with one floating-point 1198 // multiply. 1199 for (double someTestCase : someTestCases) { 1200 for (int scaleFactor : oneMultiplyScalingFactors) { 1201 testScalbCase(someTestCase, 1202 scaleFactor, 1203 someTestCase * powerOfTwoD(scaleFactor)); 1204 } 1205 } 1206 1207 // Create 2^MAX_EXPONENT 1208 double twoToTheMaxExp = 1.0; // 2^0 1209 for (int i = 0; i < Double.MAX_EXPONENT; i++) { 1210 twoToTheMaxExp *= 2.0; 1211 } 1212 1213 // Scale-up subnormal values until they all overflow 1214 for (double subnormalTestCase : subnormalTestCases) { 1215 double scale = 1.0; // 2^j 1216 1217 for (int scaleFactor = Double.MAX_EXPONENT * 2; scaleFactor < MAX_SCALE; 1218 scaleFactor++) { // MAX_SCALE -1 should cause overflow 1219 1220 testScalbCase(subnormalTestCase, 1221 scaleFactor, 1222 (Tests.ilogb(subnormalTestCase) + scaleFactor > Double.MAX_EXPONENT) ? 1223 Math.copySign(infinityD, subnormalTestCase) : // overflow 1224 // calculate right answer 1225 twoToTheMaxExp * (twoToTheMaxExp * (scale * subnormalTestCase))); 1226 scale *= 2.0; 1227 } 1228 } 1229 1230 // Scale down a large number until it underflows. By scaling 1231 // down MAX_NORMALmm, the first subnormal result will be exact 1232 // but the next one will round -- all those results can be 1233 // checked by halving a separate value in the loop. Actually, 1234 // we can keep halving and checking until the product is zero 1235 // since: 1236 // 1237 // 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact 1238 // it will round *up* 1239 // 1240 // 2. When rounding first occurs in the expected product, it 1241 // too rounds up, to 2^-MAX_EXPONENT. 1242 // 1243 // Halving expected after rounding happends to give the same 1244 // result as the scalb operation. 1245 double expected = Double_MAX_VALUEmm * 0.5f; 1246 for (int i = -1; i > -MAX_SCALE; i--) { 1247 testScalbCase(Double_MAX_VALUEmm, i, expected); 1248 1249 expected *= 0.5; 1250 } 1251 1252 // Tricky rounding tests: 1253 // Scale down a large number into subnormal range such that if 1254 // scalb is being implemented with multiple floating-point 1255 // multiplies, the value would round twice if the multiplies 1256 // were done in the wrong order. 1257 1258 double value = 0x1.000000000000bP-1; 1259 expected = 0x0.2000000000001P-1022; 1260 for (int i = 0; i < Double.MAX_EXPONENT + 2; i++) { 1261 testScalbCase(value, 1262 -1024 - i, 1263 expected); 1264 value *= 2.0; 1265 } 1266 } 1267 1268 /* ************************* ulp tests ******************************* */ 1269 1270 1271 /* 1272 * Test Math.ulp and StrictMath.ulp with +d and -d. 1273 */ testUlpCase(float f, float expected)1274 static void testUlpCase(float f, float expected) { 1275 float minus_f = -f; 1276 1277 Tests.test("Math.ulp(float)", f, 1278 Math.ulp(f), expected); 1279 Tests.test("Math.ulp(float)", minus_f, 1280 Math.ulp(minus_f), expected); 1281 Tests.test("StrictMath.ulp(float)", f, 1282 StrictMath.ulp(f), expected); 1283 Tests.test("StrictMath.ulp(float)", minus_f, 1284 StrictMath.ulp(minus_f), expected); 1285 } 1286 testUlpCase(double d, double expected)1287 static void testUlpCase(double d, double expected) { 1288 double minus_d = -d; 1289 1290 Tests.test("Math.ulp(double)", d, 1291 Math.ulp(d), expected); 1292 Tests.test("Math.ulp(double)", minus_d, 1293 Math.ulp(minus_d), expected); 1294 Tests.test("StrictMath.ulp(double)", d, 1295 StrictMath.ulp(d), expected); 1296 Tests.test("StrictMath.ulp(double)", minus_d, 1297 StrictMath.ulp(minus_d), expected); 1298 } 1299 1300 @Test testFloatUlp()1301 public void testFloatUlp() { 1302 float[] specialValues = {NaNf, 1303 Float.POSITIVE_INFINITY, 1304 +0.0f, 1305 +1.0f, 1306 +2.0f, 1307 +16.0f, 1308 +Float.MIN_VALUE, 1309 +Float_MAX_SUBNORMAL, 1310 +Float.MIN_NORMAL, 1311 +Float.MAX_VALUE 1312 }; 1313 1314 float[] specialResults = {NaNf, 1315 Float.POSITIVE_INFINITY, 1316 Float.MIN_VALUE, 1317 powerOfTwoF(-23), 1318 powerOfTwoF(-22), 1319 powerOfTwoF(-19), 1320 Float.MIN_VALUE, 1321 Float.MIN_VALUE, 1322 Float.MIN_VALUE, 1323 powerOfTwoF(104) 1324 }; 1325 1326 // Special value tests 1327 for (int i = 0; i < specialValues.length; i++) { 1328 testUlpCase(specialValues[i], specialResults[i]); 1329 } 1330 1331 // Normal exponent tests 1332 for (int i = Float.MIN_EXPONENT; i <= Float.MAX_EXPONENT; i++) { 1333 float expected; 1334 1335 // Create power of two 1336 float po2 = powerOfTwoF(i); 1337 expected = Math.scalb(1.0f, i - (FloatConsts.SIGNIFICAND_WIDTH - 1)); 1338 1339 testUlpCase(po2, expected); 1340 1341 // Generate some random bit patterns for the significand 1342 for (int j = 0; j < 10; j++) { 1343 int randSignif = rand.nextInt(); 1344 float randFloat; 1345 1346 randFloat = Float.intBitsToFloat( // Exponent 1347 (Float.floatToIntBits(po2) & 1348 (~FloatConsts.SIGNIF_BIT_MASK)) | 1349 // Significand 1350 (randSignif & 1351 FloatConsts.SIGNIF_BIT_MASK)); 1352 1353 testUlpCase(randFloat, expected); 1354 } 1355 1356 if (i > Float.MIN_EXPONENT) { 1357 float po2minus = Math.nextAfter(po2, 1358 Float.NEGATIVE_INFINITY); 1359 testUlpCase(po2minus, expected / 2.0f); 1360 } 1361 } 1362 1363 // Subnormal tests 1364 1365 /* 1366 * Start with MIN_VALUE, left shift, test high value, low 1367 * values, and random in between. 1368 * 1369 * Use nextAfter to calculate, high value of previous binade, 1370 * loop count i will indicate how many random bits, if any are 1371 * needed. 1372 */ 1373 1374 float top = Float.MIN_VALUE; 1375 for (int i = 1; 1376 i < FloatConsts.SIGNIFICAND_WIDTH; 1377 i++, top *= 2.0f) { 1378 1379 testUlpCase(top, Float.MIN_VALUE); 1380 1381 // Test largest value in next smaller binade 1382 if (i >= 3) {// (i == 1) would test 0.0; 1383 // (i == 2) would just retest MIN_VALUE 1384 testUlpCase(Math.nextAfter(top, 0.0f), 1385 Float.MIN_VALUE); 1386 1387 if (i >= 10) { 1388 // create a bit mask with (i-1) 1's in the low order 1389 // bits 1390 int mask = ~((~0) << (i - 1)); 1391 float randFloat = Float.intBitsToFloat( // Exponent 1392 Float.floatToIntBits(top) | 1393 // Significand 1394 (rand.nextInt() & mask)); 1395 1396 testUlpCase(randFloat, Float.MIN_VALUE); 1397 } 1398 } 1399 } 1400 } 1401 1402 @Test testDoubleUlp()1403 public void testDoubleUlp() { 1404 double[] specialValues = {NaNd, 1405 Double.POSITIVE_INFINITY, 1406 +0.0d, 1407 +1.0d, 1408 +2.0d, 1409 +16.0d, 1410 +Double.MIN_VALUE, 1411 +Double_MAX_SUBNORMAL, 1412 +Double.MIN_NORMAL, 1413 +Double.MAX_VALUE 1414 }; 1415 1416 double[] specialResults = {NaNf, 1417 Double.POSITIVE_INFINITY, 1418 Double.MIN_VALUE, 1419 powerOfTwoD(-52), 1420 powerOfTwoD(-51), 1421 powerOfTwoD(-48), 1422 Double.MIN_VALUE, 1423 Double.MIN_VALUE, 1424 Double.MIN_VALUE, 1425 powerOfTwoD(971) 1426 }; 1427 1428 // Special value tests 1429 for (int i = 0; i < specialValues.length; i++) { 1430 testUlpCase(specialValues[i], specialResults[i]); 1431 } 1432 1433 // Normal exponent tests 1434 for (int i = Double.MIN_EXPONENT; i <= Double.MAX_EXPONENT; i++) { 1435 double expected; 1436 1437 // Create power of two 1438 double po2 = powerOfTwoD(i); 1439 expected = Math.scalb(1.0, i - (DoubleConsts.SIGNIFICAND_WIDTH - 1)); 1440 1441 testUlpCase(po2, expected); 1442 1443 // Generate some random bit patterns for the significand 1444 for (int j = 0; j < 10; j++) { 1445 long randSignif = rand.nextLong(); 1446 double randDouble; 1447 1448 randDouble = Double.longBitsToDouble( // Exponent 1449 (Double.doubleToLongBits(po2) & 1450 (~DoubleConsts.SIGNIF_BIT_MASK)) | 1451 // Significand 1452 (randSignif & 1453 DoubleConsts.SIGNIF_BIT_MASK)); 1454 1455 testUlpCase(randDouble, expected); 1456 } 1457 1458 if (i > Double.MIN_EXPONENT) { 1459 double po2minus = Math.nextAfter(po2, 1460 Double.NEGATIVE_INFINITY); 1461 testUlpCase(po2minus, expected / 2.0f); 1462 } 1463 } 1464 1465 // Subnormal tests 1466 1467 /* 1468 * Start with MIN_VALUE, left shift, test high value, low 1469 * values, and random in between. 1470 * 1471 * Use nextAfter to calculate, high value of previous binade, 1472 * loop count i will indicate how many random bits, if any are 1473 * needed. 1474 */ 1475 1476 double top = Double.MIN_VALUE; 1477 for (int i = 1; 1478 i < DoubleConsts.SIGNIFICAND_WIDTH; 1479 i++, top *= 2.0f) { 1480 1481 testUlpCase(top, Double.MIN_VALUE); 1482 1483 // Test largest value in next smaller binade 1484 if (i >= 3) {// (i == 1) would test 0.0; 1485 // (i == 2) would just retest MIN_VALUE 1486 testUlpCase(Math.nextAfter(top, 0.0f), 1487 Double.MIN_VALUE); 1488 1489 if (i >= 10) { 1490 // create a bit mask with (i-1) 1's in the low order 1491 // bits 1492 int mask = ~((~0) << (i - 1)); 1493 double randDouble = Double.longBitsToDouble( // Exponent 1494 Double.doubleToLongBits(top) | 1495 // Significand 1496 (rand.nextLong() & mask)); 1497 1498 testUlpCase(randDouble, Double.MIN_VALUE); 1499 } 1500 } 1501 } 1502 } 1503 1504 @Test testFloatSignum()1505 public void testFloatSignum() { 1506 float[][] testCases = { 1507 {NaNf, NaNf}, 1508 {-infinityF, -1.0f}, 1509 {-Float.MAX_VALUE, -1.0f}, 1510 {-Float.MIN_NORMAL, -1.0f}, 1511 {-1.0f, -1.0f}, 1512 {-2.0f, -1.0f}, 1513 {-Float_MAX_SUBNORMAL, -1.0f}, 1514 {-Float.MIN_VALUE, -1.0f}, 1515 {-0.0f, -0.0f}, 1516 {+0.0f, +0.0f}, 1517 {Float.MIN_VALUE, 1.0f}, 1518 {Float_MAX_SUBNORMALmm, 1.0f}, 1519 {Float_MAX_SUBNORMAL, 1.0f}, 1520 {Float.MIN_NORMAL, 1.0f}, 1521 {1.0f, 1.0f}, 1522 {2.0f, 1.0f}, 1523 {Float_MAX_VALUEmm, 1.0f}, 1524 {Float.MAX_VALUE, 1.0f}, 1525 {infinityF, 1.0f} 1526 }; 1527 1528 for (float[] testCase : testCases) { 1529 Tests.test("Math.signum(float)", 1530 testCase[0], Math.signum(testCase[0]), testCase[1]); 1531 Tests.test("StrictMath.signum(float)", 1532 testCase[0], StrictMath.signum(testCase[0]), testCase[1]); 1533 } 1534 } 1535 1536 @Test testDoubleSignum()1537 public void testDoubleSignum() { 1538 double[][] testCases = { 1539 {NaNd, NaNd}, 1540 {-infinityD, -1.0}, 1541 {-Double.MAX_VALUE, -1.0}, 1542 {-Double.MIN_NORMAL, -1.0}, 1543 {-1.0, -1.0}, 1544 {-2.0, -1.0}, 1545 {-Double_MAX_SUBNORMAL, -1.0}, 1546 {-Double.MIN_VALUE, -1.0d}, 1547 {-0.0d, -0.0d}, 1548 {+0.0d, +0.0d}, 1549 {Double.MIN_VALUE, 1.0}, 1550 {Double_MAX_SUBNORMALmm, 1.0}, 1551 {Double_MAX_SUBNORMAL, 1.0}, 1552 {Double.MIN_NORMAL, 1.0}, 1553 {1.0, 1.0}, 1554 {2.0, 1.0}, 1555 {Double_MAX_VALUEmm, 1.0}, 1556 {Double.MAX_VALUE, 1.0}, 1557 {infinityD, 1.0} 1558 }; 1559 1560 for (double[] testCase : testCases) { 1561 Tests.test("Math.signum(double)", 1562 testCase[0], Math.signum(testCase[0]), testCase[1]); 1563 Tests.test("StrictMath.signum(double)", 1564 testCase[0], StrictMath.signum(testCase[0]), testCase[1]); 1565 } 1566 } 1567 } 1568