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