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