I'm trying to convert the string "999999.99" to a float, but Float.valueOf( s ) is rounding up to 1000000.00. Here's what the API says: ...it is regarded as representing an exact decimal value in the usual "computerized scientific notation"; this exact decimal value is then conceptually converted to an "infinitely precise" binary value that is then rounded to type float by the usual round-to-nearest rule of IEEE 754 floating-point arithmetic.
Does anyone know a work-around to prevent the rounding?
[This message has been edited by Bob Graffagnino (edited November 07, 2001).]
Cindy Glass
"The Hood"
Sheriff
Joined: Sep 29, 2000
Posts: 8521
posted
0
Grrrr. . . how frustrating . . . . not Float.parseFloat() not (float)Double.parseDouble() not . . .
"JavaRanch, where the deer and the Certified play" - David O'Meara
Bob Graffagnino
Ranch Hand
Joined: May 30, 2001
Posts: 81
posted
0
Go Cindy, go Cindy......
Jim Yingst
Wanderer
Sheriff
Joined: Jan 30, 2000
Posts: 18670
posted
0
A float is not precise enough to represent 999999.99 - ever. It has nothing to do with the valueOf() method - try running the following: <pre> float f = 999999.99f; System.out.println(f); </pre> A float is generally subject to roundoffs in its 8th significant digit - in this case, the roundoff goes upward to 1000000.0. The easiest way to avoid this is to use a double or BigDecimal instead. A double will generally have no roundoff until the 18 significant digit, and a BigDecimal will have none unless you tell it to round off - but BigDecimal is notably slower, so there's a tradeoff. I usually just use double for any floating-point value, unless there's a compelling reason to do otherwise.
"I'm not back." - Bill Harding, Twister
Paul Stevens
Ranch Hand
Joined: May 17, 2001
Posts: 2823
posted
0
Just be aware if the double gets large enough you need to use a formatter or get something like 9.99999999E8.
Cindy Glass
"The Hood"
Sheriff
Joined: Sep 29, 2000
Posts: 8521
posted
0
But getting it INTO the double from the String causes the rounding - so how to fix that?
Bill Krieger
Ranch Hand
Joined: Sep 27, 2001
Posts: 53
posted
0
Originally posted by Cindy Glass: But getting it INTO the double from the String causes the rounding - so how to fix that?
How about: Double.valueOf(stringVar);
Cindy Glass
"The Hood"
Sheriff
Joined: Sep 29, 2000
Posts: 8521
posted
0
If you read the API for Double.valueOf() it says
this exact decimal value is then conceptually converted to an "infinitely precise" binary value that is then rounded to type double by the usual round-to-nearest rule of IEEE 754 floating-point arithmetic.
Double d = Double.valueOf("999999.99"); System.out.println(d); float f = d.floatValue(); System.out.println(f); gets you 999999.99 1000000.00
[This message has been edited by Cindy Glass (edited November 07, 2001).]
Colin Kenworthy
Ranch Hand
Joined: Aug 06, 2001
Posts: 88
posted
0
It might be worth remembering that (and ignoring "cup-size" for a moment) that when it comes to the fractional part of a number then binary can only be exact with multiples of half, quarter, eighths, sixteenths, 1/32 etc. So what seems like a simple decimal number 0.1 may actually be an infinite decimal number 0.00011001100110011001100110... in binary. "cup-size" only makes inaccuracies more inevitable.
Jim Yingst
Wanderer
Sheriff
Joined: Jan 30, 2000
Posts: 18670
posted
0
Elaborating on that - there is more than one way to represent floating-point numbers in binary, and some formats do allow all decimal values to be represented exactly. E.g. if 0.1 is treated as 1 * (10 ^ -1) then the mantissa and exponent can both be represented exactly. Something like this is what the JLS means by the "infinitely precise" passage Cindy quotes. However, this is not the way values are stored for int or double types, so roundoff must eventually occur at some point in order so use these data types. Why doesn't Java use an "infinitely precise" form instead? Performance, I suspect.