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