1 /* 2 * Copyright 2003-2005 Sun Microsystems, Inc. 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 Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, 20 * CA 95054 USA or visit www.sun.com if you need additional information or 21 * have any questions. 22 */ 23 24 /* 25 * @test 26 * @bug 4860891 4826732 4780454 4939441 4826652 27 * @summary Tests for IEEE 754[R] recommended functions and similar methods 28 * @author Joseph D. Darcy 29 * @compile -source 1.5 IeeeRecommendedTests.java 30 * @run main IeeeRecommendedTests 31 */ 32 33 import sun.misc.FpUtils; 34 import sun.misc.DoubleConsts; 35 import sun.misc.FloatConsts; 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 = new java.util.Random(); 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)DoubleConsts.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 + FloatConsts.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 +FloatConsts.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 FloatConsts.MIN_EXPONENT - 1, 146 -FloatConsts.MAX_EXPONENT, 147 FloatConsts.MIN_EXPONENT, 148 FloatConsts.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 = FloatConsts.MIN_EXPONENT; i <= FloatConsts.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 > FloatConsts.MIN_EXPONENT) { 182 float po2minus = FpUtils.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 FloatConsts.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(FpUtils.nextAfter(top, 0.0f), 211 FloatConsts.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 FloatConsts.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 +DoubleConsts.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 DoubleConsts.MIN_EXPONENT - 1, 253 -DoubleConsts.MAX_EXPONENT, 254 DoubleConsts.MIN_EXPONENT, 255 DoubleConsts.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 = DoubleConsts.MIN_EXPONENT; i <= DoubleConsts.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 > DoubleConsts.MIN_EXPONENT) { 289 double po2minus = FpUtils.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 DoubleConsts.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(FpUtils.nextAfter(top, 0.0), 318 DoubleConsts.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 DoubleConsts.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 {FloatConsts.MIN_NORMAL, infinityF, FloatConsts.MIN_NORMAL+ 407 Float.MIN_VALUE}, 408 {FloatConsts.MIN_NORMAL, -infinityF, Float_MAX_SUBNORMAL}, 409 {FloatConsts.MIN_NORMAL, 1.0f, FloatConsts.MIN_NORMAL+ 410 Float.MIN_VALUE}, 411 {FloatConsts.MIN_NORMAL, -1.0f, Float_MAX_SUBNORMAL}, 412 {FloatConsts.MIN_NORMAL, FloatConsts.MIN_NORMAL, FloatConsts.MIN_NORMAL}, 413 414 {Float_MAX_SUBNORMAL, FloatConsts.MIN_NORMAL, FloatConsts.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 {DoubleConsts.MIN_NORMAL, infinityD, DoubleConsts.MIN_NORMAL+ 479 Double.MIN_VALUE}, 480 {DoubleConsts.MIN_NORMAL, -infinityD, Double_MAX_SUBNORMAL}, 481 {DoubleConsts.MIN_NORMAL, 1.0f, DoubleConsts.MIN_NORMAL+ 482 Double.MIN_VALUE}, 483 {DoubleConsts.MIN_NORMAL, -1.0f, Double_MAX_SUBNORMAL}, 484 {DoubleConsts.MIN_NORMAL, DoubleConsts.MIN_NORMAL,DoubleConsts.MIN_NORMAL}, 485 486 {Double_MAX_SUBNORMAL, DoubleConsts.MIN_NORMAL,DoubleConsts.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 {-FloatConsts.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, FloatConsts.MIN_NORMAL}, 543 {FloatConsts.MIN_NORMAL, FloatConsts.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 {-DoubleConsts.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, DoubleConsts.MIN_NORMAL}, 581 {DoubleConsts.MIN_NORMAL, DoubleConsts.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, -FloatConsts.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 {FloatConsts.MIN_NORMAL, Float_MAX_SUBNORMAL}, 621 {FloatConsts.MIN_NORMAL+ 622 Float.MIN_VALUE, FloatConsts.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("FpUtils.nextDown(float)", 629 testCases[i][0], FpUtils.nextDown(testCases[i][0]), testCases[i][1]); 630 } 631 632 return failures; 633 } 634 635 636 public static int testDoubleNextDown() { 637 int failures=0; 638 639 /* 640 * Each row of testCases represents one test case for nextDown; 641 * the first column is the input and the second column is the 642 * expected result. 643 */ 644 double testCases [][] = { 645 {NaNd, NaNd}, 646 {-infinityD, -infinityD}, 647 {-Double.MAX_VALUE, -infinityD}, 648 {-Double_MAX_VALUEmm, -Double.MAX_VALUE}, 649 {-Double_MAX_SUBNORMAL, -DoubleConsts.MIN_NORMAL}, 650 {-Double_MAX_SUBNORMALmm, -Double_MAX_SUBNORMAL}, 651 {-0.0d, -Double.MIN_VALUE}, 652 {+0.0d, -Double.MIN_VALUE}, 653 {Double.MIN_VALUE, 0.0d}, 654 {Double.MIN_VALUE*2, Double.MIN_VALUE}, 655 {Double_MAX_SUBNORMAL, Double_MAX_SUBNORMALmm}, 656 {DoubleConsts.MIN_NORMAL, Double_MAX_SUBNORMAL}, 657 {DoubleConsts.MIN_NORMAL+ 658 Double.MIN_VALUE, DoubleConsts.MIN_NORMAL}, 659 {Double.MAX_VALUE, Double_MAX_VALUEmm}, 660 {infinityD, Double.MAX_VALUE}, 661 }; 662 663 for(int i = 0; i < testCases.length; i++) { 664 failures+=Tests.test("FpUtils.nextDown(double)", 665 testCases[i][0], FpUtils.nextDown(testCases[i][0]), testCases[i][1]); 666 } 667 668 return failures; 669 } 670 671 672 /* ********************** boolean tests ****************************** */ 673 674 /* 675 * Combined tests for boolean functions, isFinite, isInfinite, 676 * isNaN, isUnordered. 677 */ 678 679 public static int testFloatBooleanMethods() { 680 int failures = 0; 681 682 float testCases [] = { 683 NaNf, 684 -infinityF, 685 infinityF, 686 -Float.MAX_VALUE, 687 -3.0f, 688 -1.0f, 689 -FloatConsts.MIN_NORMAL, 690 -Float_MAX_SUBNORMALmm, 691 -Float_MAX_SUBNORMAL, 692 -Float.MIN_VALUE, 693 -0.0f, 694 +0.0f, 695 Float.MIN_VALUE, 696 Float_MAX_SUBNORMALmm, 697 Float_MAX_SUBNORMAL, 698 FloatConsts.MIN_NORMAL, 699 1.0f, 700 3.0f, 701 Float_MAX_VALUEmm, 702 Float.MAX_VALUE 703 }; 704 705 for(int i = 0; i < testCases.length; i++) { 706 // isNaN 707 failures+=Tests.test("FpUtils.isNaN(float)", testCases[i], 708 FpUtils.isNaN(testCases[i]), (i ==0)); 709 710 // isFinite 711 failures+=Tests.test("FpUtils.isFinite(float)", testCases[i], 712 FpUtils.isFinite(testCases[i]), (i >= 3)); 713 714 // isInfinite 715 failures+=Tests.test("FpUtils.isInfinite(float)", testCases[i], 716 FpUtils.isInfinite(testCases[i]), (i==1 || i==2)); 717 718 // isUnorderd 719 for(int j = 0; j < testCases.length; j++) { 720 failures+=Tests.test("FpUtils.isUnordered(float, float)", testCases[i],testCases[j], 721 FpUtils.isUnordered(testCases[i],testCases[j]), (i==0 || j==0)); 722 } 723 } 724 725 return failures; 726 } 727 728 public static int testDoubleBooleanMethods() { 729 int failures = 0; 730 boolean result = false; 731 732 double testCases [] = { 733 NaNd, 734 -infinityD, 735 infinityD, 736 -Double.MAX_VALUE, 737 -3.0d, 738 -1.0d, 739 -DoubleConsts.MIN_NORMAL, 740 -Double_MAX_SUBNORMALmm, 741 -Double_MAX_SUBNORMAL, 742 -Double.MIN_VALUE, 743 -0.0d, 744 +0.0d, 745 Double.MIN_VALUE, 746 Double_MAX_SUBNORMALmm, 747 Double_MAX_SUBNORMAL, 748 DoubleConsts.MIN_NORMAL, 749 1.0d, 750 3.0d, 751 Double_MAX_VALUEmm, 752 Double.MAX_VALUE 753 }; 754 755 for(int i = 0; i < testCases.length; i++) { 756 // isNaN 757 failures+=Tests.test("FpUtils.isNaN(double)", testCases[i], 758 FpUtils.isNaN(testCases[i]), (i ==0)); 759 760 // isFinite 761 failures+=Tests.test("FpUtils.isFinite(double)", testCases[i], 762 FpUtils.isFinite(testCases[i]), (i >= 3)); 763 764 // isInfinite 765 failures+=Tests.test("FpUtils.isInfinite(double)", testCases[i], 766 FpUtils.isInfinite(testCases[i]), (i==1 || i==2)); 767 768 // isUnorderd 769 for(int j = 0; j < testCases.length; j++) { 770 failures+=Tests.test("FpUtils.isUnordered(double, double)", testCases[i],testCases[j], 771 FpUtils.isUnordered(testCases[i],testCases[j]), (i==0 || j==0)); 772 } 773 } 774 775 return failures; 776 } 777 778 /* ******************** copySign tests******************************** */ 779 780 public static int testFloatCopySign() { 781 int failures = 0; 782 783 // testCases[0] are logically positive numbers; 784 // testCases[1] are negative numbers. 785 float testCases [][] = { 786 {+0.0f, 787 Float.MIN_VALUE, 788 Float_MAX_SUBNORMALmm, 789 Float_MAX_SUBNORMAL, 790 FloatConsts.MIN_NORMAL, 791 1.0f, 792 3.0f, 793 Float_MAX_VALUEmm, 794 Float.MAX_VALUE, 795 infinityF, 796 }, 797 {-infinityF, 798 -Float.MAX_VALUE, 799 -3.0f, 800 -1.0f, 801 -FloatConsts.MIN_NORMAL, 802 -Float_MAX_SUBNORMALmm, 803 -Float_MAX_SUBNORMAL, 804 -Float.MIN_VALUE, 805 -0.0f} 806 }; 807 808 float NaNs[] = {Float.intBitsToFloat(0x7fc00000), // "positive" NaN 809 Float.intBitsToFloat(0xFfc00000)}; // "negative" NaN 810 811 // Tests shared between raw and non-raw versions 812 for(int i = 0; i < 2; i++) { 813 for(int j = 0; j < 2; j++) { 814 for(int m = 0; m < testCases[i].length; m++) { 815 for(int n = 0; n < testCases[j].length; n++) { 816 // copySign(magnitude, sign) 817 failures+=Tests.test("Math.copySign(float,float)", 818 testCases[i][m],testCases[j][n], 819 Math.copySign(testCases[i][m], testCases[j][n]), 820 (j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) ); 821 822 failures+=Tests.test("StrictMath.copySign(float,float)", 823 testCases[i][m],testCases[j][n], 824 StrictMath.copySign(testCases[i][m], testCases[j][n]), 825 (j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) ); 826 } 827 } 828 } 829 } 830 831 // For rawCopySign, NaN may effectively have either sign bit 832 // while for copySign NaNs are treated as if they always have 833 // a zero sign bit (i.e. as positive numbers) 834 for(int i = 0; i < 2; i++) { 835 for(int j = 0; j < NaNs.length; j++) { 836 for(int m = 0; m < testCases[i].length; m++) { 837 // copySign(magnitude, sign) 838 839 failures += (Math.abs(Math.copySign(testCases[i][m], NaNs[j])) == 840 Math.abs(testCases[i][m])) ? 0:1; 841 842 843 failures+=Tests.test("StrictMath.copySign(float,float)", 844 testCases[i][m], NaNs[j], 845 StrictMath.copySign(testCases[i][m], NaNs[j]), 846 Math.abs(testCases[i][m]) ); 847 } 848 } 849 } 850 851 return failures; 852 } 853 854 public static int testDoubleCopySign() { 855 int failures = 0; 856 857 // testCases[0] are logically positive numbers; 858 // testCases[1] are negative numbers. 859 double testCases [][] = { 860 {+0.0d, 861 Double.MIN_VALUE, 862 Double_MAX_SUBNORMALmm, 863 Double_MAX_SUBNORMAL, 864 DoubleConsts.MIN_NORMAL, 865 1.0d, 866 3.0d, 867 Double_MAX_VALUEmm, 868 Double.MAX_VALUE, 869 infinityD, 870 }, 871 {-infinityD, 872 -Double.MAX_VALUE, 873 -3.0d, 874 -1.0d, 875 -DoubleConsts.MIN_NORMAL, 876 -Double_MAX_SUBNORMALmm, 877 -Double_MAX_SUBNORMAL, 878 -Double.MIN_VALUE, 879 -0.0d} 880 }; 881 882 double NaNs[] = {Double.longBitsToDouble(0x7ff8000000000000L), // "positive" NaN 883 Double.longBitsToDouble(0xfff8000000000000L), // "negative" NaN 884 Double.longBitsToDouble(0x7FF0000000000001L), 885 Double.longBitsToDouble(0xFFF0000000000001L), 886 Double.longBitsToDouble(0x7FF8555555555555L), 887 Double.longBitsToDouble(0xFFF8555555555555L), 888 Double.longBitsToDouble(0x7FFFFFFFFFFFFFFFL), 889 Double.longBitsToDouble(0xFFFFFFFFFFFFFFFFL), 890 Double.longBitsToDouble(0x7FFDeadBeef00000L), 891 Double.longBitsToDouble(0xFFFDeadBeef00000L), 892 Double.longBitsToDouble(0x7FFCafeBabe00000L), 893 Double.longBitsToDouble(0xFFFCafeBabe00000L)}; 894 895 // Tests shared between Math and StrictMath versions 896 for(int i = 0; i < 2; i++) { 897 for(int j = 0; j < 2; j++) { 898 for(int m = 0; m < testCases[i].length; m++) { 899 for(int n = 0; n < testCases[j].length; n++) { 900 // copySign(magnitude, sign) 901 failures+=Tests.test("MathcopySign(double,double)", 902 testCases[i][m],testCases[j][n], 903 Math.copySign(testCases[i][m], testCases[j][n]), 904 (j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) ); 905 906 failures+=Tests.test("StrictMath.copySign(double,double)", 907 testCases[i][m],testCases[j][n], 908 StrictMath.copySign(testCases[i][m], testCases[j][n]), 909 (j==0?1.0f:-1.0f)*Math.abs(testCases[i][m]) ); 910 } 911 } 912 } 913 } 914 915 // For Math.copySign, NaN may effectively have either sign bit 916 // while for StrictMath.copySign NaNs are treated as if they 917 // always have a zero sign bit (i.e. as positive numbers) 918 for(int i = 0; i < 2; i++) { 919 for(int j = 0; j < NaNs.length; j++) { 920 for(int m = 0; m < testCases[i].length; m++) { 921 // copySign(magnitude, sign) 922 923 failures += (Math.abs(Math.copySign(testCases[i][m], NaNs[j])) == 924 Math.abs(testCases[i][m])) ? 0:1; 925 926 927 failures+=Tests.test("StrictMath.copySign(double,double)", 928 testCases[i][m], NaNs[j], 929 StrictMath.copySign(testCases[i][m], NaNs[j]), 930 Math.abs(testCases[i][m]) ); 931 } 932 } 933 } 934 935 936 return failures; 937 } 938 939 /* ************************ scalb tests ******************************* */ 940 941 static int testScalbCase(float value, int scale_factor, float expected) { 942 int failures=0; 943 944 failures+=Tests.test("Math.scalb(float,int)", 945 value, scale_factor, 946 Math.scalb(value, scale_factor), expected); 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("StrictMath.scalb(float,int)", 953 value, scale_factor, 954 StrictMath.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 return failures; 960 } 961 962 public static int testFloatScalb() { 963 int failures=0; 964 int MAX_SCALE = FloatConsts.MAX_EXPONENT + -FloatConsts.MIN_EXPONENT + 965 FloatConsts.SIGNIFICAND_WIDTH + 1; 966 967 968 // Arguments x, where scalb(x,n) is x for any n. 969 float [] identityTestCases = {NaNf, 970 -0.0f, 971 +0.0f, 972 infinityF, 973 -infinityF 974 }; 975 976 float [] subnormalTestCases = { 977 Float.MIN_VALUE, 978 3.0f*Float.MIN_VALUE, 979 Float_MAX_SUBNORMALmm, 980 Float_MAX_SUBNORMAL 981 }; 982 983 float [] someTestCases = { 984 Float.MIN_VALUE, 985 3.0f*Float.MIN_VALUE, 986 Float_MAX_SUBNORMALmm, 987 Float_MAX_SUBNORMAL, 988 FloatConsts.MIN_NORMAL, 989 1.0f, 990 2.0f, 991 3.0f, 992 (float)Math.PI, 993 Float_MAX_VALUEmm, 994 Float.MAX_VALUE 995 }; 996 997 int [] oneMultiplyScalingFactors = { 998 FloatConsts.MIN_EXPONENT, 999 FloatConsts.MIN_EXPONENT+1, 1000 -3, 1001 -2, 1002 -1, 1003 0, 1004 1, 1005 2, 1006 3, 1007 FloatConsts.MAX_EXPONENT-1, 1008 FloatConsts.MAX_EXPONENT 1009 }; 1010 1011 int [] manyScalingFactors = { 1012 Integer.MIN_VALUE, 1013 Integer.MIN_VALUE+1, 1014 -MAX_SCALE -1, 1015 -MAX_SCALE, 1016 -MAX_SCALE+1, 1017 1018 2*FloatConsts.MIN_EXPONENT-1, // -253 1019 2*FloatConsts.MIN_EXPONENT, // -252 1020 2*FloatConsts.MIN_EXPONENT+1, // -251 1021 1022 FpUtils.ilogb(Float.MIN_VALUE)-1, // -150 1023 FpUtils.ilogb(Float.MIN_VALUE), // -149 1024 -FloatConsts.MAX_EXPONENT, // -127 1025 FloatConsts.MIN_EXPONENT, // -126 1026 1027 -2, 1028 -1, 1029 0, 1030 1, 1031 2, 1032 1033 FloatConsts.MAX_EXPONENT-1, // 126 1034 FloatConsts.MAX_EXPONENT, // 127 1035 FloatConsts.MAX_EXPONENT+1, // 128 1036 1037 2*FloatConsts.MAX_EXPONENT-1, // 253 1038 2*FloatConsts.MAX_EXPONENT, // 254 1039 2*FloatConsts.MAX_EXPONENT+1, // 255 1040 1041 MAX_SCALE-1, 1042 MAX_SCALE, 1043 MAX_SCALE+1, 1044 Integer.MAX_VALUE-1, 1045 Integer.MAX_VALUE 1046 }; 1047 1048 // Test cases where scaling is always a no-op 1049 for(int i=0; i < identityTestCases.length; i++) { 1050 for(int j=0; j < manyScalingFactors.length; j++) { 1051 failures += testScalbCase(identityTestCases[i], 1052 manyScalingFactors[j], 1053 identityTestCases[i]); 1054 } 1055 } 1056 1057 // Test cases where result is 0.0 or infinity due to magnitude 1058 // of the scaling factor 1059 for(int i=0; i < someTestCases.length; i++) { 1060 for(int j=0; j < manyScalingFactors.length; j++) { 1061 int scaleFactor = manyScalingFactors[j]; 1062 if (Math.abs(scaleFactor) >= MAX_SCALE) { 1063 float value = someTestCases[i]; 1064 failures+=testScalbCase(value, 1065 scaleFactor, 1066 FpUtils.copySign( (scaleFactor>0?infinityF:0.0f), value) ); 1067 } 1068 } 1069 } 1070 1071 // Test cases that could be done with one floating-point 1072 // multiply. 1073 for(int i=0; i < someTestCases.length; i++) { 1074 for(int j=0; j < oneMultiplyScalingFactors.length; j++) { 1075 int scaleFactor = oneMultiplyScalingFactors[j]; 1076 float value = someTestCases[i]; 1077 1078 failures+=testScalbCase(value, 1079 scaleFactor, 1080 value*powerOfTwoF(scaleFactor)); 1081 } 1082 } 1083 1084 // Create 2^MAX_EXPONENT 1085 float twoToTheMaxExp = 1.0f; // 2^0 1086 for(int i = 0; i < FloatConsts.MAX_EXPONENT; i++) 1087 twoToTheMaxExp *=2.0f; 1088 1089 // Scale-up subnormal values until they all overflow 1090 for(int i=0; i < subnormalTestCases.length; i++) { 1091 float scale = 1.0f; // 2^j 1092 float value = subnormalTestCases[i]; 1093 1094 for(int j=FloatConsts.MAX_EXPONENT*2; j < MAX_SCALE; j++) { // MAX_SCALE -1 should cause overflow 1095 int scaleFactor = j; 1096 1097 failures+=testScalbCase(value, 1098 scaleFactor, 1099 (FpUtils.ilogb(value) +j > FloatConsts.MAX_EXPONENT ) ? 1100 FpUtils.copySign(infinityF, value) : // overflow 1101 // calculate right answer 1102 twoToTheMaxExp*(twoToTheMaxExp*(scale*value)) ); 1103 scale*=2.0f; 1104 } 1105 } 1106 1107 // Scale down a large number until it underflows. By scaling 1108 // down MAX_NORMALmm, the first subnormal result will be exact 1109 // but the next one will round -- all those results can be 1110 // checked by halving a separate value in the loop. Actually, 1111 // we can keep halving and checking until the product is zero 1112 // since: 1113 // 1114 // 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact 1115 // it will round *up* 1116 // 1117 // 2. When rounding first occurs in the expected product, it 1118 // too rounds up, to 2^-MAX_EXPONENT. 1119 // 1120 // Halving expected after rounding happends to give the same 1121 // result as the scalb operation. 1122 float expected = Float_MAX_VALUEmm *0.5f; 1123 for(int i = -1; i > -MAX_SCALE; i--) { 1124 failures+=testScalbCase(Float_MAX_VALUEmm, i, expected); 1125 1126 expected *= 0.5f; 1127 } 1128 1129 // Tricky rounding tests: 1130 // Scale down a large number into subnormal range such that if 1131 // scalb is being implemented with multiple floating-point 1132 // multiplies, the value would round twice if the multiplies 1133 // were done in the wrong order. 1134 1135 float value = 0x8.0000bP-5f; 1136 expected = 0x1.00001p-129f; 1137 1138 for(int i = 0; i < 129; i++) { 1139 failures+=testScalbCase(value, 1140 -127-i, 1141 expected); 1142 value *=2.0f; 1143 } 1144 1145 return failures; 1146 } 1147 1148 static int testScalbCase(double value, int scale_factor, double expected) { 1149 int failures=0; 1150 1151 failures+=Tests.test("Math.scalb(double,int)", 1152 value, scale_factor, 1153 Math.scalb(value, scale_factor), expected); 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("StrictMath.scalb(double,int)", 1160 value, scale_factor, 1161 StrictMath.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 return failures; 1168 } 1169 1170 public static int testDoubleScalb() { 1171 int failures=0; 1172 int MAX_SCALE = DoubleConsts.MAX_EXPONENT + -DoubleConsts.MIN_EXPONENT + 1173 DoubleConsts.SIGNIFICAND_WIDTH + 1; 1174 1175 1176 // Arguments x, where scalb(x,n) is x for any n. 1177 double [] identityTestCases = {NaNd, 1178 -0.0, 1179 +0.0, 1180 infinityD, 1181 }; 1182 1183 double [] subnormalTestCases = { 1184 Double.MIN_VALUE, 1185 3.0d*Double.MIN_VALUE, 1186 Double_MAX_SUBNORMALmm, 1187 Double_MAX_SUBNORMAL 1188 }; 1189 1190 double [] someTestCases = { 1191 Double.MIN_VALUE, 1192 3.0d*Double.MIN_VALUE, 1193 Double_MAX_SUBNORMALmm, 1194 Double_MAX_SUBNORMAL, 1195 DoubleConsts.MIN_NORMAL, 1196 1.0d, 1197 2.0d, 1198 3.0d, 1199 Math.PI, 1200 Double_MAX_VALUEmm, 1201 Double.MAX_VALUE 1202 }; 1203 1204 int [] oneMultiplyScalingFactors = { 1205 DoubleConsts.MIN_EXPONENT, 1206 DoubleConsts.MIN_EXPONENT+1, 1207 -3, 1208 -2, 1209 -1, 1210 0, 1211 1, 1212 2, 1213 3, 1214 DoubleConsts.MAX_EXPONENT-1, 1215 DoubleConsts.MAX_EXPONENT 1216 }; 1217 1218 int [] manyScalingFactors = { 1219 Integer.MIN_VALUE, 1220 Integer.MIN_VALUE+1, 1221 -MAX_SCALE -1, 1222 -MAX_SCALE, 1223 -MAX_SCALE+1, 1224 1225 2*DoubleConsts.MIN_EXPONENT-1, // -2045 1226 2*DoubleConsts.MIN_EXPONENT, // -2044 1227 2*DoubleConsts.MIN_EXPONENT+1, // -2043 1228 1229 FpUtils.ilogb(Double.MIN_VALUE)-1, // -1076 1230 FpUtils.ilogb(Double.MIN_VALUE), // -1075 1231 -DoubleConsts.MAX_EXPONENT, // -1023 1232 DoubleConsts.MIN_EXPONENT, // -1022 1233 1234 -2, 1235 -1, 1236 0, 1237 1, 1238 2, 1239 1240 DoubleConsts.MAX_EXPONENT-1, // 1022 1241 DoubleConsts.MAX_EXPONENT, // 1023 1242 DoubleConsts.MAX_EXPONENT+1, // 1024 1243 1244 2*DoubleConsts.MAX_EXPONENT-1, // 2045 1245 2*DoubleConsts.MAX_EXPONENT, // 2046 1246 2*DoubleConsts.MAX_EXPONENT+1, // 2047 1247 1248 MAX_SCALE-1, 1249 MAX_SCALE, 1250 MAX_SCALE+1, 1251 Integer.MAX_VALUE-1, 1252 Integer.MAX_VALUE 1253 }; 1254 1255 // Test cases where scaling is always a no-op 1256 for(int i=0; i < identityTestCases.length; i++) { 1257 for(int j=0; j < manyScalingFactors.length; j++) { 1258 failures += testScalbCase(identityTestCases[i], 1259 manyScalingFactors[j], 1260 identityTestCases[i]); 1261 } 1262 } 1263 1264 // Test cases where result is 0.0 or infinity due to magnitude 1265 // of the scaling factor 1266 for(int i=0; i < someTestCases.length; i++) { 1267 for(int j=0; j < manyScalingFactors.length; j++) { 1268 int scaleFactor = manyScalingFactors[j]; 1269 if (Math.abs(scaleFactor) >= MAX_SCALE) { 1270 double value = someTestCases[i]; 1271 failures+=testScalbCase(value, 1272 scaleFactor, 1273 FpUtils.copySign( (scaleFactor>0?infinityD:0.0), value) ); 1274 } 1275 } 1276 } 1277 1278 // Test cases that could be done with one floating-point 1279 // multiply. 1280 for(int i=0; i < someTestCases.length; i++) { 1281 for(int j=0; j < oneMultiplyScalingFactors.length; j++) { 1282 int scaleFactor = oneMultiplyScalingFactors[j]; 1283 double value = someTestCases[i]; 1284 1285 failures+=testScalbCase(value, 1286 scaleFactor, 1287 value*powerOfTwoD(scaleFactor)); 1288 } 1289 } 1290 1291 // Create 2^MAX_EXPONENT 1292 double twoToTheMaxExp = 1.0; // 2^0 1293 for(int i = 0; i < DoubleConsts.MAX_EXPONENT; i++) 1294 twoToTheMaxExp *=2.0; 1295 1296 // Scale-up subnormal values until they all overflow 1297 for(int i=0; i < subnormalTestCases.length; i++) { 1298 double scale = 1.0; // 2^j 1299 double value = subnormalTestCases[i]; 1300 1301 for(int j=DoubleConsts.MAX_EXPONENT*2; j < MAX_SCALE; j++) { // MAX_SCALE -1 should cause overflow 1302 int scaleFactor = j; 1303 1304 failures+=testScalbCase(value, 1305 scaleFactor, 1306 (FpUtils.ilogb(value) +j > DoubleConsts.MAX_EXPONENT ) ? 1307 FpUtils.copySign(infinityD, value) : // overflow 1308 // calculate right answer 1309 twoToTheMaxExp*(twoToTheMaxExp*(scale*value)) ); 1310 scale*=2.0; 1311 } 1312 } 1313 1314 // Scale down a large number until it underflows. By scaling 1315 // down MAX_NORMALmm, the first subnormal result will be exact 1316 // but the next one will round -- all those results can be 1317 // checked by halving a separate value in the loop. Actually, 1318 // we can keep halving and checking until the product is zero 1319 // since: 1320 // 1321 // 1. If the scalb of MAX_VALUEmm is subnormal and *not* exact 1322 // it will round *up* 1323 // 1324 // 2. When rounding first occurs in the expected product, it 1325 // too rounds up, to 2^-MAX_EXPONENT. 1326 // 1327 // Halving expected after rounding happends to give the same 1328 // result as the scalb operation. 1329 double expected = Double_MAX_VALUEmm *0.5f; 1330 for(int i = -1; i > -MAX_SCALE; i--) { 1331 failures+=testScalbCase(Double_MAX_VALUEmm, i, expected); 1332 1333 expected *= 0.5; 1334 } 1335 1336 // Tricky rounding tests: 1337 // Scale down a large number into subnormal range such that if 1338 // scalb is being implemented with multiple floating-point 1339 // multiplies, the value would round twice if the multiplies 1340 // were done in the wrong order. 1341 1342 double value = 0x1.000000000000bP-1; 1343 expected = 0x0.2000000000001P-1022; 1344 for(int i = 0; i < DoubleConsts.MAX_EXPONENT+2; i++) { 1345 failures+=testScalbCase(value, 1346 -1024-i, 1347 expected); 1348 value *=2.0; 1349 } 1350 1351 return failures; 1352 } 1353 1354 /* ************************* ulp tests ******************************* */ 1355 1356 1357 /* 1358 * Test Math.ulp and StrictMath.ulp with +d and -d. 1359 */ 1360 static int testUlpCase(float f, float expected) { 1361 float minus_f = -f; 1362 int failures=0; 1363 1364 failures+=Tests.test("Math.ulp(float)", f, 1365 Math.ulp(f), expected); 1366 failures+=Tests.test("Math.ulp(float)", minus_f, 1367 Math.ulp(minus_f), expected); 1368 failures+=Tests.test("StrictMath.ulp(float)", f, 1369 StrictMath.ulp(f), expected); 1370 failures+=Tests.test("StrictMath.ulp(float)", minus_f, 1371 StrictMath.ulp(minus_f), expected); 1372 return failures; 1373 } 1374 1375 static int testUlpCase(double d, double expected) { 1376 double minus_d = -d; 1377 int failures=0; 1378 1379 failures+=Tests.test("Math.ulp(double)", d, 1380 Math.ulp(d), expected); 1381 failures+=Tests.test("Math.ulp(double)", minus_d, 1382 Math.ulp(minus_d), expected); 1383 failures+=Tests.test("StrictMath.ulp(double)", d, 1384 StrictMath.ulp(d), expected); 1385 failures+=Tests.test("StrictMath.ulp(double)", minus_d, 1386 StrictMath.ulp(minus_d), expected); 1387 return failures; 1388 } 1389 1390 public static int testFloatUlp() { 1391 int failures = 0; 1392 float [] specialValues = {NaNf, 1393 Float.POSITIVE_INFINITY, 1394 +0.0f, 1395 +1.0f, 1396 +2.0f, 1397 +16.0f, 1398 +Float.MIN_VALUE, 1399 +Float_MAX_SUBNORMAL, 1400 +FloatConsts.MIN_NORMAL, 1401 +Float.MAX_VALUE 1402 }; 1403 1404 float [] specialResults = {NaNf, 1405 Float.POSITIVE_INFINITY, 1406 Float.MIN_VALUE, 1407 powerOfTwoF(-23), 1408 powerOfTwoF(-22), 1409 powerOfTwoF(-19), 1410 Float.MIN_VALUE, 1411 Float.MIN_VALUE, 1412 Float.MIN_VALUE, 1413 powerOfTwoF(104) 1414 }; 1415 1416 // Special value tests 1417 for(int i = 0; i < specialValues.length; i++) { 1418 failures += testUlpCase(specialValues[i], specialResults[i]); 1419 } 1420 1421 1422 // Normal exponent tests 1423 for(int i = FloatConsts.MIN_EXPONENT; i <= FloatConsts.MAX_EXPONENT; i++) { 1424 float expected; 1425 1426 // Create power of two 1427 float po2 = powerOfTwoF(i); 1428 expected = FpUtils.scalb(1.0f, i - (FloatConsts.SIGNIFICAND_WIDTH-1)); 1429 1430 failures += testUlpCase(po2, expected); 1431 1432 // Generate some random bit patterns for the significand 1433 for(int j = 0; j < 10; j++) { 1434 int randSignif = rand.nextInt(); 1435 float randFloat; 1436 1437 randFloat = Float.intBitsToFloat( // Exponent 1438 (Float.floatToIntBits(po2)& 1439 (~FloatConsts.SIGNIF_BIT_MASK)) | 1440 // Significand 1441 (randSignif & 1442 FloatConsts.SIGNIF_BIT_MASK) ); 1443 1444 failures += testUlpCase(randFloat, expected); 1445 } 1446 1447 if (i > FloatConsts.MIN_EXPONENT) { 1448 float po2minus = FpUtils.nextAfter(po2, 1449 Float.NEGATIVE_INFINITY); 1450 failures += testUlpCase(po2minus, expected/2.0f); 1451 } 1452 } 1453 1454 // Subnormal tests 1455 1456 /* 1457 * Start with MIN_VALUE, left shift, test high value, low 1458 * values, and random in between. 1459 * 1460 * Use nextAfter to calculate, high value of previous binade, 1461 * loop count i will indicate how many random bits, if any are 1462 * needed. 1463 */ 1464 1465 float top=Float.MIN_VALUE; 1466 for( int i = 1; 1467 i < FloatConsts.SIGNIFICAND_WIDTH; 1468 i++, top *= 2.0f) { 1469 1470 failures += testUlpCase(top, Float.MIN_VALUE); 1471 1472 // Test largest value in next smaller binade 1473 if (i >= 3) {// (i == 1) would test 0.0; 1474 // (i == 2) would just retest MIN_VALUE 1475 testUlpCase(FpUtils.nextAfter(top, 0.0f), 1476 Float.MIN_VALUE); 1477 1478 if( i >= 10) { 1479 // create a bit mask with (i-1) 1's in the low order 1480 // bits 1481 int mask = ~((~0)<<(i-1)); 1482 float randFloat = Float.intBitsToFloat( // Exponent 1483 Float.floatToIntBits(top) | 1484 // Significand 1485 (rand.nextInt() & mask ) ) ; 1486 1487 failures += testUlpCase(randFloat, Float.MIN_VALUE); 1488 } 1489 } 1490 } 1491 1492 return failures; 1493 } 1494 1495 public static int testDoubleUlp() { 1496 int failures = 0; 1497 double [] specialValues = {NaNd, 1498 Double.POSITIVE_INFINITY, 1499 +0.0d, 1500 +1.0d, 1501 +2.0d, 1502 +16.0d, 1503 +Double.MIN_VALUE, 1504 +Double_MAX_SUBNORMAL, 1505 +DoubleConsts.MIN_NORMAL, 1506 +Double.MAX_VALUE 1507 }; 1508 1509 double [] specialResults = {NaNf, 1510 Double.POSITIVE_INFINITY, 1511 Double.MIN_VALUE, 1512 powerOfTwoD(-52), 1513 powerOfTwoD(-51), 1514 powerOfTwoD(-48), 1515 Double.MIN_VALUE, 1516 Double.MIN_VALUE, 1517 Double.MIN_VALUE, 1518 powerOfTwoD(971) 1519 }; 1520 1521 // Special value tests 1522 for(int i = 0; i < specialValues.length; i++) { 1523 failures += testUlpCase(specialValues[i], specialResults[i]); 1524 } 1525 1526 1527 // Normal exponent tests 1528 for(int i = DoubleConsts.MIN_EXPONENT; i <= DoubleConsts.MAX_EXPONENT; i++) { 1529 double expected; 1530 1531 // Create power of two 1532 double po2 = powerOfTwoD(i); 1533 expected = FpUtils.scalb(1.0, i - (DoubleConsts.SIGNIFICAND_WIDTH-1)); 1534 1535 failures += testUlpCase(po2, expected); 1536 1537 // Generate some random bit patterns for the significand 1538 for(int j = 0; j < 10; j++) { 1539 long randSignif = rand.nextLong(); 1540 double randDouble; 1541 1542 randDouble = Double.longBitsToDouble( // Exponent 1543 (Double.doubleToLongBits(po2)& 1544 (~DoubleConsts.SIGNIF_BIT_MASK)) | 1545 // Significand 1546 (randSignif & 1547 DoubleConsts.SIGNIF_BIT_MASK) ); 1548 1549 failures += testUlpCase(randDouble, expected); 1550 } 1551 1552 if (i > DoubleConsts.MIN_EXPONENT) { 1553 double po2minus = FpUtils.nextAfter(po2, 1554 Double.NEGATIVE_INFINITY); 1555 failures += testUlpCase(po2minus, expected/2.0f); 1556 } 1557 } 1558 1559 // Subnormal tests 1560 1561 /* 1562 * Start with MIN_VALUE, left shift, test high value, low 1563 * values, and random in between. 1564 * 1565 * Use nextAfter to calculate, high value of previous binade, 1566 * loop count i will indicate how many random bits, if any are 1567 * needed. 1568 */ 1569 1570 double top=Double.MIN_VALUE; 1571 for( int i = 1; 1572 i < DoubleConsts.SIGNIFICAND_WIDTH; 1573 i++, top *= 2.0f) { 1574 1575 failures += testUlpCase(top, Double.MIN_VALUE); 1576 1577 // Test largest value in next smaller binade 1578 if (i >= 3) {// (i == 1) would test 0.0; 1579 // (i == 2) would just retest MIN_VALUE 1580 testUlpCase(FpUtils.nextAfter(top, 0.0f), 1581 Double.MIN_VALUE); 1582 1583 if( i >= 10) { 1584 // create a bit mask with (i-1) 1's in the low order 1585 // bits 1586 int mask = ~((~0)<<(i-1)); 1587 double randDouble = Double.longBitsToDouble( // Exponent 1588 Double.doubleToLongBits(top) | 1589 // Significand 1590 (rand.nextLong() & mask ) ) ; 1591 1592 failures += testUlpCase(randDouble, Double.MIN_VALUE); 1593 } 1594 } 1595 } 1596 1597 return failures; 1598 } 1599 1600 public static int testFloatSignum() { 1601 int failures = 0; 1602 float testCases [][] = { 1603 {NaNf, NaNf}, 1604 {-infinityF, -1.0f}, 1605 {-Float.MAX_VALUE, -1.0f}, 1606 {-FloatConsts.MIN_NORMAL, -1.0f}, 1607 {-1.0f, -1.0f}, 1608 {-2.0f, -1.0f}, 1609 {-Float_MAX_SUBNORMAL, -1.0f}, 1610 {-Float.MIN_VALUE, -1.0f}, 1611 {-0.0f, -0.0f}, 1612 {+0.0f, +0.0f}, 1613 {Float.MIN_VALUE, 1.0f}, 1614 {Float_MAX_SUBNORMALmm, 1.0f}, 1615 {Float_MAX_SUBNORMAL, 1.0f}, 1616 {FloatConsts.MIN_NORMAL, 1.0f}, 1617 {1.0f, 1.0f}, 1618 {2.0f, 1.0f}, 1619 {Float_MAX_VALUEmm, 1.0f}, 1620 {Float.MAX_VALUE, 1.0f}, 1621 {infinityF, 1.0f} 1622 }; 1623 1624 for(int i = 0; i < testCases.length; i++) { 1625 failures+=Tests.test("Math.signum(float)", 1626 testCases[i][0], Math.signum(testCases[i][0]), testCases[i][1]); 1627 failures+=Tests.test("StrictMath.signum(float)", 1628 testCases[i][0], StrictMath.signum(testCases[i][0]), testCases[i][1]); 1629 } 1630 1631 return failures; 1632 } 1633 1634 public static int testDoubleSignum() { 1635 int failures = 0; 1636 double testCases [][] = { 1637 {NaNd, NaNd}, 1638 {-infinityD, -1.0}, 1639 {-Double.MAX_VALUE, -1.0}, 1640 {-DoubleConsts.MIN_NORMAL, -1.0}, 1641 {-1.0, -1.0}, 1642 {-2.0, -1.0}, 1643 {-Double_MAX_SUBNORMAL, -1.0}, 1644 {-Double.MIN_VALUE, -1.0d}, 1645 {-0.0d, -0.0d}, 1646 {+0.0d, +0.0d}, 1647 {Double.MIN_VALUE, 1.0}, 1648 {Double_MAX_SUBNORMALmm, 1.0}, 1649 {Double_MAX_SUBNORMAL, 1.0}, 1650 {DoubleConsts.MIN_NORMAL, 1.0}, 1651 {1.0, 1.0}, 1652 {2.0, 1.0}, 1653 {Double_MAX_VALUEmm, 1.0}, 1654 {Double.MAX_VALUE, 1.0}, 1655 {infinityD, 1.0} 1656 }; 1657 1658 for(int i = 0; i < testCases.length; i++) { 1659 failures+=Tests.test("Math.signum(double)", 1660 testCases[i][0], Math.signum(testCases[i][0]), testCases[i][1]); 1661 failures+=Tests.test("StrictMath.signum(double)", 1662 testCases[i][0], StrictMath.signum(testCases[i][0]), testCases[i][1]); 1663 } 1664 1665 return failures; 1666 } 1667 1668 1669 public static void main(String argv[]) { 1670 int failures = 0; 1671 1672 failures += testFloatGetExponent(); 1673 failures += testDoubleGetExponent(); 1674 1675 failures += testFloatNextAfter(); 1676 failures += testDoubleNextAfter(); 1677 1678 failures += testFloatNextUp(); 1679 failures += testDoubleNextUp(); 1680 1681 failures += testFloatNextDown(); 1682 failures += testDoubleNextDown(); 1683 1684 failures += testFloatBooleanMethods(); 1685 failures += testDoubleBooleanMethods(); 1686 1687 failures += testFloatCopySign(); 1688 failures += testDoubleCopySign(); 1689 1690 failures += testFloatScalb(); 1691 failures += testDoubleScalb(); 1692 1693 failures += testFloatUlp(); 1694 failures += testDoubleUlp(); 1695 1696 failures += testFloatSignum(); 1697 failures += testDoubleSignum(); 1698 1699 if (failures > 0) { 1700 System.err.println("Testing the recommended functions incurred " 1701 + failures + " failures."); 1702 throw new RuntimeException(); 1703 } 1704 } 1705 }