Duplicate :
|
|
Relates :
|
|
Relates :
|
|
Relates :
|
Name: dkC59003 Date: 11/18/98 This is almost same bug as reported in #4023198 (jdk 1.0.2, Float.toString produces incorrect results). Indeed 4023198 is closed, Float.toString() still continue to produce incorrect results for some other arguments. Error arises in following releases: JDK 1.0.2: fails under: solaris-sparc, win32 JDK 1.1.x: fails under: solaris-x86 , win32 JDK 1.2 : fails under: solaris-x86 (both with and without JIT) The problem is the following: JLS section 20.9.16 uniquely defines canonical result of Float.toString(x) for every float value x. However, the JDK releases listed above fail to produce correct result of Float.toString(x) for some particular values x. Below are the samples: ------------------------------------ fpm03504_bug.java: import java.lang.Float; class fpm03504_bug { static void main (String args[]) { float b59 = Float.intBitsToFloat(0x5d000000); // 2**59 float b60 = Float.intBitsToFloat(0x5d800000); // 2**60 float b61 = Float.intBitsToFloat(0x5e000000); // 2**61 float b62 = Float.intBitsToFloat(0x5e800000); // 2**62 String s59 = Float.toString(b59); String s60 = Float.toString(b60); String s61 = Float.toString(b61); String s62 = Float.toString(b62); String c59 = "5.7646075E17"; // canonical representations String c60 = "1.1529215E18"; // computed under JDK 1.2 String c61 = "2.30584301E18"; // fcsR / solaris-sparc String c62 = "4.611686E18"; boolean e59 = s59.compareTo(c59) == 0; boolean e60 = s60.compareTo(c60) == 0; boolean e61 = s61.compareTo(c61) == 0; boolean e62 = s62.compareTo(c62) == 0; System.out.println("b59: "+s59+"\t" + (e59? " -- Ok": " instead of: "+c59)); System.out.println("b60: "+s60+"\t" + (e60? " -- Ok": " instead of: "+c60)); System.out.println("b61: "+s61+"\t" + (e61? " -- Ok": " instead of: "+c61)); System.out.println("b62: "+s62+"\t" + (e62? " -- Ok": " instead of: "+c62)); } } ---------------------- produces under some JDK releases: java fpm03504_bug b59: 5.7646788E17 instead of: 5.7646075E17 b60: 1.15293577E18 instead of: 1.1529215E18 b61: 2.30587156E18 instead of: 2.30584301E18 b62: 4.6116886E18 instead of: 4.611686E18 -------------------------------------------------- I have found, that b59,b60,b61,b62 are the only float values having the form 2**n, which bring Float.toString() to fail. ====================================================================== Name: boT120536 Date: 01/22/2001 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) The library routines for converting floats to Strings still have some bugs in them. According to the specs of Float.toString: "How many digits must be printed for the fractional part of m or a? There must be at least one digit to represent the fractional part, and beyond that as many, but only as many, more digits as are needed to uniquely distinguish the argument value from adjacent values of type float. That is, suppose that x is the exact mathematical value represented by the decimal representation produced by this method for a finite nonzero argument f. Then f must be the float value nearest to x; or, if two float values are equally close to x then f must be one of them and the least significant bit of the significand of f must be 0." Take the number 123456789.0f. This rounds to the exact value 123456792 (the bit pattern 0x4ceb79a3, by Float.floatToIntBits). The nearest two floats are Float.intBitsToFloat(0x4ceb79a2), which is exactly 123456784, and Float.intBitsToFloat(0x4ceb79a4), which is exactly 1234567800. The representation 1.2345679E8 is closer to 123456792 than 123456784, so no further accuracy is allowed. However, System.out.println("" + 123456789f) produces 1.23456792E8, where the second digit '2' is spurious, according to the specs. (Review ID: 113581) ====================================================================== ###@###.### 2004-11-11 21:42:37 GMT
|