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