RFC 7019078: Double.parseDouble() converts some subnormal numbers incorrectly

Brian Burkhalter brian.burkhalter at oracle.com
Wed Jun 26 00:13:33 UTC 2013


The test case in the description of this issue

http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=7019078

passes after the integration of this changeset

http://hg.openjdk.java.net/jdk8/tl/jdk/rev/a88f6f4d279f

except when the exponent has the value -1074. Here is the pertinent code from the test:

            BigDecimal TWO = BigDecimal.valueOf(2);
            BigDecimal ulp_BD = new BigDecimal(Double.MIN_VALUE);
            double d = Math.scalb(1.0, -1074); // == Double.MIN_VALUE

            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);
            }

The output of the above is

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

For the case of 2^(-1074), lowerBound is 2^(-1074) - 2^(-1075) = Double.MIN_VALUE/2 which per the IEEE 754 round-to-nearest rule rounds correctly to zero. For this case, upperBound is equivalent to 2^(-1074) + 2^(-1075) which is halfway between 2^(-1074) and 2*2^(-1074). As round-to-nearest mandates that the tie with the least significant bit equal to zero be chosen, the correct outcome after rounding is 2*2^(-1074) which is what is obtained. The test case is therefore incorrect for both lower and upper bounds when the exponent is -1074.

As a result of all but one case having been fixed and that last case being an incorrect test, this issue may be closed as a duplicate unless there are objections to the contrary.

Brian


More information about the core-libs-dev mailing list