Java Reference
In-Depth Information
loss of precision [JLS 5.1.2]. (The others are long to float and long to double .)
The initial value of f is so large that adding 50 to it and converting the result to a float produces
the same value as simply converting f to a float . In other words, (float)2000000000 ==
2000000050 , so the expression f < START + 50 is false before the loop body has executed even
once, and the loop body never gets a chance to run.
Fixing this program is as simple as changing the type of the loop variable from a float to an int .
This avoids all the imprecision associated with floatingpoint computation:
for ( int i = START; i < START + 50; i++)
count++;
Without using a computer, how could you possibly have known that 2,000,000,050 has the same
float representation as 2,000,000,000? The key is to observe that 2,000,000,000 has ten factors of
2: It begins with a 2 and has nine factors of 10, each of which is 5 x 2. This means that the binary
representation of 2,000,000,000 ends in ten 0s. The binary representation of 50 requires only six
bits, so adding 50 to 2,000,000,000 doesn't influence any bit higher than the sixth from the right. In
particular, the seventh and eighth bits from the right are still 0. Promoting this 31-bit int to a float
with 24 bits of precision rounds between the seventh and eighth bits, which simply discards the
rightmost seven bits. The rightmost six bits are the only ones on which 2,000,000,000 and
2,000,000,050 differ, so their float representations are identical.
The moral of this puzzle is simple: Do not use floating-point loop indices , because it can lead to
unpredictable behavior. If you need a floating-point value in the body of a loop, take the int or
long loop index and convert it to a float or double . You may lose precision when converting an
int or long to a float or a long to a double , but at least it will not affect the loop itself. When
you use floating-point, use double rather than float unless you are certain that float provides
enough precision and you have a compelling performance need to use float . The times when it's
appropriate to use float rather than double are few and far between.
The lesson for language designers, yet again, is that silent loss of precision can be very confusing to
programmers. See Puzzle 31 for further discussion.
< Day Day Up >
 
 
Search WWH ::




Custom Search