8043740: Doubles with large exponents overflow to Infinity incorrectly
Summary: Modify test of exponent overflow to account for subsequent decrement.
Reviewed-by: darcy
Contributed-by: Sandipan Razzaque <me@sandipan.net>
--- a/jdk/src/java.base/share/classes/sun/misc/FloatingDecimal.java Mon Sep 22 10:47:27 2014 +0200
+++ b/jdk/src/java.base/share/classes/sun/misc/FloatingDecimal.java Mon Sep 22 10:41:45 2014 -0700
@@ -1992,21 +1992,32 @@
break expLoop; // stop parsing exponent.
}
}
- int expLimit = BIG_DECIMAL_EXPONENT+nDigits+nTrailZero;
- if ( expOverflow || ( expVal > expLimit ) ){
- //
- // The intent here is to end up with
- // infinity or zero, as appropriate.
- // The reason for yielding such a small decExponent,
- // rather than something intuitive such as
- // expSign*Integer.MAX_VALUE, is that this value
- // is subject to further manipulation in
- // doubleValue() and floatValue(), and I don't want
- // it to be able to cause overflow there!
- // (The only way we can get into trouble here is for
- // really outrageous nDigits+nTrailZero, such as 2 billion. )
- //
- decExp = expSign*expLimit;
+ int expLimit = BIG_DECIMAL_EXPONENT + nDigits + nTrailZero;
+ if (expOverflow || (expVal > expLimit)) {
+ // There is still a chance that the exponent will be safe to
+ // use: if it would eventually decrease due to a negative
+ // decExp, and that number is below the limit. We check for
+ // that here.
+ if (!expOverflow && (expSign == 1 && decExp < 0)
+ && (expVal + decExp) < expLimit) {
+ // Cannot overflow: adding a positive and negative number.
+ decExp += expVal;
+ } else {
+ //
+ // The intent here is to end up with
+ // infinity or zero, as appropriate.
+ // The reason for yielding such a small decExponent,
+ // rather than something intuitive such as
+ // expSign*Integer.MAX_VALUE, is that this value
+ // is subject to further manipulation in
+ // doubleValue() and floatValue(), and I don't want
+ // it to be able to cause overflow there!
+ // (The only way we can get into trouble here is for
+ // really outrageous nDigits+nTrailZero, such as 2
+ // billion.)
+ //
+ decExp = expSign * expLimit;
+ }
} else {
// this should not overflow, since we tested
// for expVal > (MAX+N), where N >= abs(decExp)
--- a/jdk/test/java/lang/Double/ParseDouble.java Mon Sep 22 10:47:27 2014 +0200
+++ b/jdk/test/java/lang/Double/ParseDouble.java Mon Sep 22 10:41:45 2014 -0700
@@ -512,6 +512,21 @@
"2.2250738585072014e-308", // Double.MIN_NORMAL
"2.2250738585072012e-308", // near Double.MIN_NORMAL
+
+ "1.7976931348623158e+308", // near MAX_VALUE + ulp(MAX_VALUE)/2
+ "1.7976931348623159e+308", // near MAX_VALUE + ulp(MAX_VALUE)
+
+ "2.4703282292062329e-324", // above MIN_VALUE/2
+ "2.4703282292062327e-324", // MIN_VALUE/2
+ "2.4703282292062325e-324", // below MIN_VALUE/2
+
+ // 1e308 with leading zeros
+
+ "0.0000000000001e321",
+ "00.000000000000000001e326",
+ "00000.000000000000000001e326",
+ "000.0000000000000000001e327",
+ "0.00000000000000000001e328",
};
static String paddedBadStrings[];