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