src/java.base/share/classes/sun/misc/FloatingDecimal.java
Print this page
rev 10699 : 8043740: Doubles with large exponents overflow to Infinity incorrectly
Summary: Modify test of exponent overflow to account for subsequent decrement.
Reviewed-by: TBD
Contributed-by: Sandipan Razzaque <me@sandipan.net>
@@ -1990,25 +1990,36 @@
} else {
i--; // back up.
break expLoop; // stop parsing exponent.
}
}
- int expLimit = BIG_DECIMAL_EXPONENT+nDigits+nTrailZero;
- if ( expOverflow || ( expVal > 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 ((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. )
+ // really outrageous nDigits+nTrailZero, such as 2
+ // billion.)
//
- decExp = expSign*expLimit;
+ decExp = expSign * expLimit;
+ }
} else {
// this should not overflow, since we tested
// for expVal > (MAX+N), where N >= abs(decExp)
decExp = decExp + expSign*expVal;
}