RFR for 8043740 (Doubles with large exponents overflow to Infinity incorrectly)
Sandipan Razzaque
me at sandipan.net
Mon Jun 2 14:08:06 UTC 2014
Hi all -
I've made a quick revision to that last patch. Please find inline the
latest link + patch.
http://www.sandipan.net/public/webrevs/8043740/webrev.01/
Cheers,
SR
--- old/src/share/classes/sun/misc/FloatingDecimal.java 2014-06-02
09:32:20.000000000 -0400
+++ new/src/share/classes/sun/misc/FloatingDecimal.java 2014-06-02
09:32:19.000000000 -0400
@@ -1994,19 +1994,29 @@
}
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;
+ // 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 + decExp;
+ } 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)
--- /dev/null 2014-06-02 09:32:21.000000000 -0400
+++ new/test/java/lang/Double/Bug8043740.java 2014-06-02
09:32:20.000000000 -0400
@@ -0,0 +1,41 @@
+/*
+ * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights reserved.
+ * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
+ *
+ * This code is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 only, as
+ * published by the Free Software Foundation.
+ *
+ * This code is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ * version 2 for more details (a copy is included in the LICENSE file that
+ * accompanied this code).
+ *
+ * You should have received a copy of the GNU General Public License version
+ * 2 along with this work; if not, write to the Free Software Foundation,
+ * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
+ * or visit www.oracle.com if you need additional information or have any
+ * questions.
+ */
+
+/*
+ * @test
+ * @bug 8043740
+ * @summary Test for Double.parseDouble incorrect normalization of exponent.
+ */
+public class Bug8043740 {
+
+ public static void main(String[] args) {
+ String text = "00.000000000000000001e326";
+ double expected = Double.parseDouble("1e308");
+ double value = Double.parseDouble(text);
+ if (Double.compare(expected, value) != 0) {
+ throw new RuntimeException("String [" + text +
+ "] was incorrectly parsed to [" + value + "]");
+ }
+ }
+
+}
Sandipan Razzaque | www.sandipan.net
On Sun, Jun 1, 2014 at 10:55 PM, Sandipan Razzaque <me at sandipan.net> wrote:
> Hi Brian/all,
>
> Fix for the above-mentioned bug is complete. If you (or anyone else as
> appropriate) could please review the changes and let me know of your
> comments that would be great!
>
> Link for the webrev:
>
> http://www.sandipan.net/public/webrevs/8043740/webrev.00/
>
> The patch is inlined below my signature.
>
> Cheers,
> SR
>
>
> --- old/src/share/classes/sun/misc/FloatingDecimal.java 2014-06-01
> 22:33:34.947651253 -0400
> +++ new/src/share/classes/sun/misc/FloatingDecimal.java 2014-06-01
> 22:33:34.827651251 -0400
> @@ -1992,7 +1992,10 @@
> break expLoop; // stop parsing exponent.
> }
> }
> - int expLimit = BIG_DECIMAL_EXPONENT+nDigits+nTrailZero;
> +
> + int expLimit = BIG_DECIMAL_EXPONENT + nDigits + nTrailZero
> + - (nLeadZero - decPt);
> +
> if ( expOverflow || ( expVal > expLimit ) ){
> //
> // The intent here is to end up with
> --- /dev/null 2014-05-28 21:22:08.061671015 -0400
> +++ new/test/java/lang/Double/Bug8043740.java 2014-06-01 22:33:35.227651260
> -0400
> @@ -0,0 +1,40 @@
> +/*
> + * Copyright (c) 2001, 2014, Oracle and/or its affiliates. All rights
> reserved.
> + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
> + *
> + * This code is free software; you can redistribute it and/or modify it
> + * under the terms of the GNU General Public License version 2 only, as
> + * published by the Free Software Foundation.
> + *
> + * This code is distributed in the hope that it will be useful, but WITHOUT
> + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
> + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
> + * version 2 for more details (a copy is included in the LICENSE file that
> + * accompanied this code).
> + *
> + * You should have received a copy of the GNU General Public License
> version
> + * 2 along with this work; if not, write to the Free Software Foundation,
> + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
> + *
> + * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
> + * or visit www.oracle.com if you need additional information or have any
> + * questions.
> + */
> +
> +/*
> + * @test
> + * @bug 8043740
> + * @summary Test for Double.parseDouble incorrect normalization of
> exponent.
> + */
> +public class Bug8043740 {
> +
> + public static void main(String[] args) {
> + String text326 = "00.000000000000000001e326"; // expect 1e308
> + double value326 = Double.parseDouble(text326);
> + if (Double.isInfinite(value326)) {
> + throw new RuntimeException("String [" + text326 +
> + "] was incorrectly parsed to Infinity.");
> + }
> + }
> +
> +}
>
>
More information about the core-libs-dev
mailing list