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