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 ----------