JDK-4396272 : Parsing doubles fails to follow IEEE for largest decimal that should yield 0
  • Type: Bug
  • Component: core-libs
  • Sub-Component: java.lang
  • Affected Version: 1.3.0,6u16
  • Priority: P4
  • Status: Resolved
  • Resolution: Won't Fix
  • OS: windows_98,windows_vista
  • CPU: x86
  • Submitted: 2000-12-08
  • Updated: 2013-06-21
  • Resolved: 2013-06-21
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 8
8Fixed
Related Reports
Relates :  
Relates :  
Description
Name: boT120536			Date: 12/07/2000


java version "1.3.0"
Java(TM) 2 Runtime Environment, Standard Edition (build 1.3.0-C)
Java HotSpot(TM) Client VM (build 1.3.0-C, mixed mode)



Using java.math.BigDecimal, I found the exact decimal value of Double.MIN_VALUE
/ 2, listed below.  This number is exactly halfway between two IEEE754 doubles
(Double.longBitsToDouble(0x1L) and Double.longBitsToDouble(0x0L)), so it should
round to the version with least significant bit 0.  However, this would mean it
rounds to 0, which is invalid, by JLS 3.10.2.  Therefore, this number should
produce a compile-time error.

Adding any non-zero digits at the end of the decimal listing make the literal
valid, as round to nearest would then round up, and javac correctly accepts
those values.  Likewise, replacing the last digit 5 with anything to make the
number smaller (for example, 49999), also has the correct behavior where javac
rejects the number as too small.

class example {
  // This number must be on one line.
  // It should be a compile-time error, because it rounds to 0
  double d =
0.000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000000000000000000000000000000000000000000000000000000000000000000000000000000
00000247032822920623272088284396434110686182529901307162382212792841250337753635
10437593264991818081799618989828234772285886546332835517796989819938739800539093
90631503565951557022639229085839244910518443593180284993653615250031937045767824
92193656236698636584807570015857692699037063119282795585513329278343384093519780
15531246597263579574622766465272827220056374006485499977096599470454020828166226
23785739345073633900796776193057750674017632467360096895134053553745851666113422
37666786041621596804619144672918403005300575308490487653917113865916462395249126
23653881879636239373280423891018672348497668235089863388587925628302755995657524
45550725518931369083625477918694866799496832404970582102851318545139621383772282
6145437693412532098591327667236328125;
}

The similar case of Float.MIN_VALUE / 2,
0.000000000000000000000000000000000000000000000700649232162408535461864791644958
065640130970938257885878534141944895541342930300743319094181060791015625f,
correctly produces the expected compile-time error.  Likewise, 4.9e-324 / 2
produces 0, showing that the value does indeed round to zero.
(Review ID: 113164) 
======================================================================

As the compiler just uses the library, this is a library bug:

frog$ cat -n T.java
     1	class T {
     2	    public static void main(String[] args) {
     3		String s = 
     4	"0.000000000000000000000000000000000000000000000000000000000000000000000000000000" +
     5	"00000000000000000000000000000000000000000000000000000000000000000000000000000000" +
     6	"00000000000000000000000000000000000000000000000000000000000000000000000000000000" +
     7	"00000000000000000000000000000000000000000000000000000000000000000000000000000000" +
     8	"00000247032822920623272088284396434110686182529901307162382212792841250337753635" +
     9	"10437593264991818081799618989828234772285886546332835517796989819938739800539093" +
    10	"90631503565951557022639229085839244910518443593180284993653615250031937045767824" +
    11	"92193656236698636584807570015857692699037063119282795585513329278343384093519780" +
    12	"15531246597263579574622766465272827220056374006485499977096599470454020828166226" +
    13	"23785739345073633900796776193057750674017632467360096895134053553745851666113422" +
    14	"37666786041621596804619144672918403005300575308490487653917113865916462395249126" +
    15	"23653881879636239373280423891018672348497668235089863388587925628302755995657524" +
    16	"45550725518931369083625477918694866799496832404970582102851318545139621383772282" +
    17	"6145437693412532098591327667236328125";
    18		double d = Double.parseDouble(s);
    19		System.out.println("" + d);
    20	    }
    21	}
frog$ /usr/local/java/jdk1.4.0/solsparc/bin/javac T.java
frog$ /usr/local/java/jdk1.4.0/solsparc/bin/java T
4.9E-324
frog$ 

neal.gafter@Eng 2000-12-08
###@###.### 2004-11-11 21:41:02 GMT

Comments
This has been fixed in jdk8 (see backport issue). There are no plans at this time to fix this in jdk7u so I am closing this issue. If it is decided later to back-porting this to jdk7u then this issue can be re-opened.
21-06-2013

core-libs-dev posting: http://mail.openjdk.java.net/pipermail/core-libs-dev/2013-February/014553.html
15-02-2013

SUGGESTED FIX See patches from OpenJDK bugzilla
23-07-2012

CONVERTED DATA BugTraq+ Release Management Values COMMIT TO FIX: dragon
14-06-2004

EVALUATION The compiler just uses the library to parse doubles; this is a library bug. neal.gafter@Eng 2000-12-08 Library fails as described; half way case between 0 and Double.MIN_VALUE gets rounded up to Double.MIN_VALUE instead of getting rounded down to 0.0. ###@###.### 2002-05-22
08-12-2000