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