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