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).]
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.
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);
Joined: Sep 29, 2000
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).]
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.
Joined: Jan 30, 2000
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.