test/java/lang/Double/ParseHexFloatingPoint.java

Print this page


   1 /*
   2  * Copyright (c) 2003, 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 4826774
  27  * @summary Numerical tests for hexadecimal inputs to parseDouble, parseFloat
  28  * @author Joseph D. Darcy
  29  */
  30 
  31 
  32 import java.util.regex.*;
  33 import sun.misc.FpUtils;
  34 import sun.misc.DoubleConsts;
  35 
  36 public class ParseHexFloatingPoint {
  37     private ParseHexFloatingPoint(){}
  38 
  39     public static final double infinityD = Double.POSITIVE_INFINITY;
  40     public static final double NaND = Double.NaN;
  41 
  42     static int test(String testName, String input,
  43                     double result, double expected) {
  44         int failures =0;
  45 
  46         if (Double.compare(result, expected) != 0 ) {
  47             System.err.println("Failure for " + testName +
  48                                ": For input " + input +
  49                                " expected " + expected +
  50                                " got " + result + ".");
  51         }
  52 
  53         return failures;


 210             new PairSD("0x0.8p0",               8.0/16.0),
 211             new PairSD("0x0.9p0",               9.0/16.0),
 212             new PairSD("0x0.ap0",               10.0/16.0),
 213             new PairSD("0x0.bp0",               11.0/16.0),
 214             new PairSD("0x0.cp0",               12.0/16.0),
 215             new PairSD("0x0.dp0",               13.0/16.0),
 216             new PairSD("0x0.ep0",               14.0/16.0),
 217             new PairSD("0x0.fp0",               15.0/16.0),
 218 
 219             // Half-way case between zero and MIN_VALUE rounds down to
 220             // zero
 221             new PairSD("0x1.0p-1075",           0.0),
 222 
 223             // Slighly more than half-way case between zero and
 224             // MIN_VALUES rounds up to zero.
 225             new PairSD("0x1.1p-1075",                   Double.MIN_VALUE),
 226             new PairSD("0x1.000000000001p-1075",        Double.MIN_VALUE),
 227             new PairSD("0x1.000000000000001p-1075",     Double.MIN_VALUE),
 228 
 229             // More subnormal rounding tests
 230             new PairSD("0x0.fffffffffffff7fffffp-1022", FpUtils.nextDown(DoubleConsts.MIN_NORMAL)),
 231             new PairSD("0x0.fffffffffffff8p-1022",      DoubleConsts.MIN_NORMAL),
 232             new PairSD("0x0.fffffffffffff800000001p-1022",DoubleConsts.MIN_NORMAL),
 233             new PairSD("0x0.fffffffffffff80000000000000001p-1022",DoubleConsts.MIN_NORMAL),
 234             new PairSD("0x1.0p-1022",                   DoubleConsts.MIN_NORMAL),
 235 
 236 
 237             // Large value and overflow rounding tests
 238             new PairSD("0x1.fffffffffffffp1023",        Double.MAX_VALUE),
 239             new PairSD("0x1.fffffffffffff0000000p1023", Double.MAX_VALUE),
 240             new PairSD("0x1.fffffffffffff4p1023",       Double.MAX_VALUE),
 241             new PairSD("0x1.fffffffffffff7fffffp1023",  Double.MAX_VALUE),
 242             new PairSD("0x1.fffffffffffff8p1023",       infinityD),
 243             new PairSD("0x1.fffffffffffff8000001p1023", infinityD),
 244 
 245             new PairSD("0x1.ffffffffffffep1023",        FpUtils.nextDown(Double.MAX_VALUE)),
 246             new PairSD("0x1.ffffffffffffe0000p1023",    FpUtils.nextDown(Double.MAX_VALUE)),
 247             new PairSD("0x1.ffffffffffffe8p1023",       FpUtils.nextDown(Double.MAX_VALUE)),
 248             new PairSD("0x1.ffffffffffffe7p1023",       FpUtils.nextDown(Double.MAX_VALUE)),
 249             new PairSD("0x1.ffffffffffffeffffffp1023",  Double.MAX_VALUE),
 250             new PairSD("0x1.ffffffffffffe8000001p1023", Double.MAX_VALUE),
 251         };
 252 
 253         for (int i = 0; i < testCases.length; i++) {
 254             failures += testCase(testCases[i].s,testCases[i].d);
 255         }
 256 
 257         failures += significandAlignmentTests();
 258 
 259         {
 260             java.util.Random rand = new java.util.Random();
 261             // Consistency check; double => hexadecimal => double
 262             // preserves the original value.
 263             for(int i = 0; i < 1000; i++) {
 264                 double d = rand.nextDouble();
 265                 failures += testCase(Double.toHexString(d), d);
 266             }
 267         }
 268 
 269         return failures;
 270     }
 271 
 272     /*
 273      * Verify rounding works the same regardless of how the
 274      * significand is aligned on input.  A useful extension could be
 275      * to have this sort of test for strings near the overflow
 276      * threshold.
 277      */
 278     static int significandAlignmentTests() {
 279         int failures = 0;
 280                 // baseSignif * 2^baseExp = nextDown(2.0)
 281         long [] baseSignifs = {
 282             0x1ffffffffffffe00L,
 283             0x1fffffffffffff00L
 284         };
 285 
 286         double [] answers = {
 287             FpUtils.nextDown(FpUtils.nextDown(2.0)),
 288             FpUtils.nextDown(2.0),
 289             2.0
 290         };
 291 
 292         int baseExp = -60;
 293         int count = 0;
 294         for(int i = 0; i < 2; i++) {
 295             for(long j = 0; j <= 0xfL; j++) {
 296                 for(long k = 0; k <= 8; k+= 4) { // k = {0, 4, 8}
 297                     long base = baseSignifs[i];
 298                     long testValue = base | (j<<4) | k;
 299 
 300                     int offset = 0;
 301                     // Calculate when significand should be incremented
 302                     // see table 4.7 in Koren book
 303 
 304                     if ((base & 0x100L) == 0L ) { // lsb is 0
 305                         if ( (j >= 8L) &&         // round is 1
 306                              ((j & 0x7L) != 0 || k != 0 ) ) // sticky is 1
 307                             offset = 1;
 308                     }


   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 4826774
  27  * @summary Numerical tests for hexadecimal inputs to parseDouble, parseFloat
  28  * @author Joseph D. Darcy
  29  */
  30 
  31 
  32 import java.util.regex.*;

  33 import sun.misc.DoubleConsts;
  34 
  35 public class ParseHexFloatingPoint {
  36     private ParseHexFloatingPoint(){}
  37 
  38     public static final double infinityD = Double.POSITIVE_INFINITY;
  39     public static final double NaND = Double.NaN;
  40 
  41     static int test(String testName, String input,
  42                     double result, double expected) {
  43         int failures =0;
  44 
  45         if (Double.compare(result, expected) != 0 ) {
  46             System.err.println("Failure for " + testName +
  47                                ": For input " + input +
  48                                " expected " + expected +
  49                                " got " + result + ".");
  50         }
  51 
  52         return failures;


 209             new PairSD("0x0.8p0",               8.0/16.0),
 210             new PairSD("0x0.9p0",               9.0/16.0),
 211             new PairSD("0x0.ap0",               10.0/16.0),
 212             new PairSD("0x0.bp0",               11.0/16.0),
 213             new PairSD("0x0.cp0",               12.0/16.0),
 214             new PairSD("0x0.dp0",               13.0/16.0),
 215             new PairSD("0x0.ep0",               14.0/16.0),
 216             new PairSD("0x0.fp0",               15.0/16.0),
 217 
 218             // Half-way case between zero and MIN_VALUE rounds down to
 219             // zero
 220             new PairSD("0x1.0p-1075",           0.0),
 221 
 222             // Slighly more than half-way case between zero and
 223             // MIN_VALUES rounds up to zero.
 224             new PairSD("0x1.1p-1075",                   Double.MIN_VALUE),
 225             new PairSD("0x1.000000000001p-1075",        Double.MIN_VALUE),
 226             new PairSD("0x1.000000000000001p-1075",     Double.MIN_VALUE),
 227 
 228             // More subnormal rounding tests
 229             new PairSD("0x0.fffffffffffff7fffffp-1022", Math.nextDown(DoubleConsts.MIN_NORMAL)),
 230             new PairSD("0x0.fffffffffffff8p-1022",      DoubleConsts.MIN_NORMAL),
 231             new PairSD("0x0.fffffffffffff800000001p-1022",DoubleConsts.MIN_NORMAL),
 232             new PairSD("0x0.fffffffffffff80000000000000001p-1022",DoubleConsts.MIN_NORMAL),
 233             new PairSD("0x1.0p-1022",                   DoubleConsts.MIN_NORMAL),
 234 
 235 
 236             // Large value and overflow rounding tests
 237             new PairSD("0x1.fffffffffffffp1023",        Double.MAX_VALUE),
 238             new PairSD("0x1.fffffffffffff0000000p1023", Double.MAX_VALUE),
 239             new PairSD("0x1.fffffffffffff4p1023",       Double.MAX_VALUE),
 240             new PairSD("0x1.fffffffffffff7fffffp1023",  Double.MAX_VALUE),
 241             new PairSD("0x1.fffffffffffff8p1023",       infinityD),
 242             new PairSD("0x1.fffffffffffff8000001p1023", infinityD),
 243 
 244             new PairSD("0x1.ffffffffffffep1023",        Math.nextDown(Double.MAX_VALUE)),
 245             new PairSD("0x1.ffffffffffffe0000p1023",    Math.nextDown(Double.MAX_VALUE)),
 246             new PairSD("0x1.ffffffffffffe8p1023",       Math.nextDown(Double.MAX_VALUE)),
 247             new PairSD("0x1.ffffffffffffe7p1023",       Math.nextDown(Double.MAX_VALUE)),
 248             new PairSD("0x1.ffffffffffffeffffffp1023",  Double.MAX_VALUE),
 249             new PairSD("0x1.ffffffffffffe8000001p1023", Double.MAX_VALUE),
 250         };
 251 
 252         for (int i = 0; i < testCases.length; i++) {
 253             failures += testCase(testCases[i].s,testCases[i].d);
 254         }
 255 
 256         failures += significandAlignmentTests();
 257 
 258         {
 259             java.util.Random rand = new java.util.Random();
 260             // Consistency check; double => hexadecimal => double
 261             // preserves the original value.
 262             for(int i = 0; i < 1000; i++) {
 263                 double d = rand.nextDouble();
 264                 failures += testCase(Double.toHexString(d), d);
 265             }
 266         }
 267 
 268         return failures;
 269     }
 270 
 271     /*
 272      * Verify rounding works the same regardless of how the
 273      * significand is aligned on input.  A useful extension could be
 274      * to have this sort of test for strings near the overflow
 275      * threshold.
 276      */
 277     static int significandAlignmentTests() {
 278         int failures = 0;
 279                 // baseSignif * 2^baseExp = nextDown(2.0)
 280         long [] baseSignifs = {
 281             0x1ffffffffffffe00L,
 282             0x1fffffffffffff00L
 283         };
 284 
 285         double [] answers = {
 286             Math.nextDown(Math.nextDown(2.0)),
 287             Math.nextDown(2.0),
 288             2.0
 289         };
 290 
 291         int baseExp = -60;
 292         int count = 0;
 293         for(int i = 0; i < 2; i++) {
 294             for(long j = 0; j <= 0xfL; j++) {
 295                 for(long k = 0; k <= 8; k+= 4) { // k = {0, 4, 8}
 296                     long base = baseSignifs[i];
 297                     long testValue = base | (j<<4) | k;
 298 
 299                     int offset = 0;
 300                     // Calculate when significand should be incremented
 301                     // see table 4.7 in Koren book
 302 
 303                     if ((base & 0x100L) == 0L ) { // lsb is 0
 304                         if ( (j >= 8L) &&         // round is 1
 305                              ((j & 0x7L) != 0 || k != 0 ) ) // sticky is 1
 306                             offset = 1;
 307                     }