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 }