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