src/share/classes/sun/misc/FloatingDecimal.java

Print this page
rev 6572 : 8024356: Double.parseDouble() is slow for long Strings
Summary: Clamp nDigits to MAX_NDIGITS.
Reviewed-by: bpb, drchase, shade
Contributed-by: Dmitry Nadezhin <dmitry.nadezhin@oracle.com>

@@ -68,10 +68,19 @@
     static final int    maxDecimalDigits = 15;
     static final int    maxDecimalExponent = 308;
     static final int    minDecimalExponent = -324;
     static final int    bigDecimalExponent = 324; // i.e. abs(minDecimalExponent)
 
+    //
+    // The value below is chosen as a conservative threshold. It
+    // can be demonstrated that a decimal ulp less than 10^(-1075)
+    // is enough to guarantee correctness. Compensation is also made
+    // for the binary mantissa which takes 53 binary digits, or
+    // 17 decimal ones. Hence 1075 + 17 =~ 1100.
+    //
+    static final int    MAX_NDIGITS = 1100;
+
     static final long   highbyte = 0xff00000000000000L;
     static final long   highbit  = 0x8000000000000000L;
     static final long   lowbytes = ~highbyte;
 
     static final int    singleSignMask =    0x80000000;

@@ -1466,10 +1475,14 @@
              * The hard part is adjusting it, by comparison
              * with FDBigInt arithmetic.
              * Formulate the EXACT big-number result as
              * bigD0 * 10^exp
              */
+            if (nDigits > MAX_NDIGITS) {
+                nDigits = MAX_NDIGITS + 1;
+                digits[MAX_NDIGITS] = '1';
+            }
             FDBigInt bigD0 = new FDBigInt( lValue, digits, kDigits, nDigits );
             exp   = decExponent - nDigits;
 
             correctionLoop:
             while(true){