Uploaded image for project: 'JDK'
  1. JDK
  2. JDK-7019078

Double.parseDouble() converts some subnormal numbers incorrectly

XMLWordPrintable

    • Icon: Bug Bug
    • Resolution: Duplicate
    • Icon: P4 P4
    • None
    • 6u23
    • core-libs
    • x86
    • windows_xp

      FULL PRODUCT VERSION :
      java version "1.6.0_23"
      Java(TM) SE Runtime Environment (build 1.6.0_23-b05)
      Java HotSpot(TM) Client VM (build 19.0-b09, mixed mode)

      ADDITIONAL OS VERSION INFORMATION :
      Microsoft Windows XP [Version 5.1.2600]

      EXTRA RELEVANT SYSTEM CONFIGURATION :
      I am running against a version of Java updated by the FPUpdater tool, although I think my results apply to prior versions.

      A DESCRIPTION OF THE PROBLEM :
      I ran the testcase found at http://hg.openjdk.java.net/jdk6/jdk6/jdk/rev/d00080320e43. It tries to verify that certain subnormal numbers convert to negative powers of two. It fails; here's the output:

      Testing subnormal powers of two.
      Exponent -1074, unexpected upper bound converted to 0x0.0000000000002p-1022, not 0x0.0000000000001p-1022.
      Exponent -1072, unexpected lower bound converted to 0x0.0000000000003p-1022, not 0x0.0000000000004p-1022.
      Exponent -1070, unexpected lower bound converted to 0x0.000000000000fp-1022, not 0x0.000000000001p-1022.
      Exponent -1069, unexpected lower bound converted to 0x0.000000000001fp-1022, not 0x0.000000000002p-1022.
      Exponent -1068, unexpected lower bound converted to 0x0.000000000003fp-1022, not 0x0.000000000004p-1022.
      Exponent -1067, unexpected lower bound converted to 0x0.000000000007fp-1022, not 0x0.000000000008p-1022.
      Exponent -1066, unexpected lower bound converted to 0x0.00000000000ffp-1022, not 0x0.00000000001p-1022.
      Exponent -1064, unexpected lower bound converted to 0x0.00000000003ffp-1022, not 0x0.00000000004p-1022.
      Exponent -1063, unexpected lower bound converted to 0x0.00000000007ffp-1022, not 0x0.00000000008p-1022.
      Exponent -1062, unexpected lower bound converted to 0x0.0000000000fffp-1022, not 0x0.0000000001p-1022.
      Exponent -1060, unexpected lower bound converted to 0x0.0000000003fffp-1022, not 0x0.0000000004p-1022.
      Exponent -1059, unexpected lower bound converted to 0x0.0000000007fffp-1022, not 0x0.0000000008p-1022.
      Exponent -1058, unexpected lower bound converted to 0x0.000000000ffffp-1022, not 0x0.000000001p-1022.
      Exponent -1057, unexpected lower bound converted to 0x0.000000001ffffp-1022, not 0x0.000000002p-1022.
      Exponent -1056, unexpected lower bound converted to 0x0.000000003ffffp-1022, not 0x0.000000004p-1022.
      Exponent -1055, unexpected lower bound converted to 0x0.000000007ffffp-1022, not 0x0.000000008p-1022.
      Exponent -1054, unexpected lower bound converted to 0x0.00000000fffffp-1022, not 0x0.00000001p-1022.
      Exponent -1053, unexpected lower bound converted to 0x0.00000001fffffp-1022, not 0x0.00000002p-1022.
      Exponent -1052, unexpected lower bound converted to 0x0.00000003fffffp-1022, not 0x0.00000004p-1022.
      Exponent -1051, unexpected lower bound converted to 0x0.00000007fffffp-1022, not 0x0.00000008p-1022.
      Exponent -1049, unexpected lower bound converted to 0x0.0000001ffffffp-1022, not 0x0.0000002p-1022.
      Exponent -1048, unexpected lower bound converted to 0x0.0000003ffffffp-1022, not 0x0.0000004p-1022.
      Exponent -1046, unexpected lower bound converted to 0x0.000000fffffffp-1022, not 0x0.000001p-1022.
      Exponent -1044, unexpected lower bound converted to 0x0.000003fffffffp-1022, not 0x0.000004p-1022.
      Exponent -1043, unexpected lower bound converted to 0x0.000007fffffffp-1022, not 0x0.000008p-1022.
      Exponent -1042, unexpected lower bound converted to 0x0.00000ffffffffp-1022, not 0x0.00001p-1022.
      Exponent -1041, unexpected lower bound converted to 0x0.00001ffffffffp-1022, not 0x0.00002p-1022.
      Exponent -1040, unexpected lower bound converted to 0x0.00003ffffffffp-1022, not 0x0.00004p-1022.
      Exponent -1039, unexpected lower bound converted to 0x0.00007ffffffffp-1022, not 0x0.00008p-1022.
      Exponent -1038, unexpected lower bound converted to 0x0.0000fffffffffp-1022, not 0x0.0001p-1022.
      Exponent -1037, unexpected lower bound converted to 0x0.0001fffffffffp-1022, not 0x0.0002p-1022.
      Exponent -1036, unexpected lower bound converted to 0x0.0003fffffffffp-1022, not 0x0.0004p-1022.
      Exponent -1035, unexpected lower bound converted to 0x0.0007fffffffffp-1022, not 0x0.0008p-1022.
      Exponent -1034, unexpected lower bound converted to 0x0.000ffffffffffp-1022, not 0x0.001p-1022.
      Exponent -1033, unexpected lower bound converted to 0x0.001ffffffffffp-1022, not 0x0.002p-1022.
      Exponent -1032, unexpected lower bound converted to 0x0.003ffffffffffp-1022, not 0x0.004p-1022.
      Exponent -1031, unexpected lower bound converted to 0x0.007ffffffffffp-1022, not 0x0.008p-1022.
      Exponent -1030, unexpected lower bound converted to 0x0.00fffffffffffp-1022, not 0x0.01p-1022.
      Exponent -1029, unexpected lower bound converted to 0x0.01fffffffffffp-1022, not 0x0.02p-1022.
      Exponent -1028, unexpected lower bound converted to 0x0.03fffffffffffp-1022, not 0x0.04p-1022.
      Exponent -1027, unexpected lower bound converted to 0x0.07fffffffffffp-1022, not 0x0.08p-1022.
      Exponent -1026, unexpected lower bound converted to 0x0.0ffffffffffffp-1022, not 0x0.1p-1022.
      Exponent -1025, unexpected lower bound converted to 0x0.1ffffffffffffp-1022, not 0x0.2p-1022.
      Exponent -1024, unexpected lower bound converted to 0x0.3ffffffffffffp-1022, not 0x0.4p-1022.
      Exponent -1023, unexpected lower bound converted to 0x0.7ffffffffffffp-1022, not 0x0.8p-1022.
      Exponent -1022, unexpected lower bound converted to 0x0.fffffffffffffp-1022, not 0x1.0p-1022.


      STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
      Run testcase below.

      EXPECTED VERSUS ACTUAL BEHAVIOR :
      EXPECTED -
      Conversions to negative powers of two, as specified in the testcase output, with one exception -- the first line:

      Exponent -1074, unexpected upper bound converted to 0x0.0000000000002p-1022, not 0x0.0000000000001p-1022.

      This is an error in the testcase, since 2^-1074+2^-1074 = 2^-1073 (in other words, the conversion is right, and the testcase's expectations are wrong).
      ACTUAL -
      Conversions that are 1 ULP below the correct answer (see testcase output).

      REPRODUCIBILITY :
      This bug can be reproduced always.

      ---------- BEGIN SOURCE ----------
      // From http://hg.openjdk.java.net/jdk6/jdk6/jdk/rev/d00080320e43
      import java.math.BigDecimal;

      class jdk6_testcase {
       /**
       * For each subnormal power of two, test at boundaries of
       * region that should convert to that value.
       */
       private static void testSubnormalPowers() {
       BigDecimal TWO = BigDecimal.valueOf(2);
       // An ulp is the same for all subnormal values
       BigDecimal ulp_BD = new BigDecimal(Double.MIN_VALUE);

       System.out.println("Testing subnormal powers of two.");
       for(int i = -1074; i <= -1022; i++) {
       double d = Math.scalb(1.0, i);

       /*
       * The region [d - ulp/2, d + ulp/2] should round to d.
       */
       BigDecimal d_BD = new BigDecimal(d);

       BigDecimal lowerBound = d_BD.subtract(ulp_BD.divide(TWO));
       BigDecimal upperBound = d_BD.add(ulp_BD.divide(TWO));

       double convertedLowerBound = Double.parseDouble(lowerBound.toString());
       double convertedUpperBound = Double.parseDouble(upperBound.toString());

       if (convertedLowerBound != d) {
       System.out.printf("Exponent %d, unexpected lower bound converted to %a, not %a.%n",
       i, convertedLowerBound, d);
       }

       if (convertedUpperBound != d) {
       System.out.printf("Exponent %d, unexpected upper bound converted to %a, not %a.%n",
       i, convertedUpperBound, d);
       }
       }
       }

       public static void main(String[] args) throws Exception {
         testSubnormalPowers();
       }
      }
      ---------- END SOURCE ----------

            bpb Brian Burkhalter
            webbuggrp Webbug Group
            Votes:
            0 Vote for this issue
            Watchers:
            2 Start watching this issue

              Created:
              Updated:
              Resolved:
              Imported:
              Indexed: