The following code:
public class Example034 {public static void main (string[] args) {int count = 0;int start = 2000000000;for (float f = start ; F < start + 64; f++) {count++;} System.out.println (count); count = 0; System.out.println ("Add 1 after the value of the loop control condition ..."); for (float f = start; F < start + 65; f++) {count++;} System.out.println (count);}}
Output Result:
0 after adding 1 to the value of the loop control condition ...
Results Analysis:
Analyze the first loop, which is only executed when the loop control variable F ratio (float) (start+64) is small. (start+64) The initial type is int, which is automatically performed from int to float, which is at the cost of loss accuracy. Since the initial value of F is too large to add 64 to it, and then the result is converted to float, the resulting value is equal to the value of converting f directly to float. So the first loop was not executed, and the result 0 was printed. However, after the first loop execution finishes printing, why does the second loop become an infinite loop with no output?
First, let's look at how we know if two large floats are equal. such as 2000000000 and 2000000064. The key is to observe that 2, 000, 000, 000 10 factors are 2: it is a 2 times 9 10, and each 10 is 5x2. (5*2) ^9 = = 2^10*5^9,2 10 times The square is multiplied by 5 of the 9 parties), which means that 2, 000, 000, 000 of the binary representation is terminated with 10 0. The binary representation of 64 only requires 7 bits, so adding 64 to 2, 000, 000, 000 does not affect any bit other than the 7 bit on the right. In particular, the 8th digit coming from the right is still 0. Lifting the 31-bit int to float with 24-bit precision is rounded at the 8th bit, discarding the rightmost 7 bits directly. The rightmost 7 bits are the difference between 2, 000, 000, 000 and 2, 000, 000, 064, so their float representation is the same. (The blue Word part indicates the uncertainty is correct )
If you follow the above, then the second loop of the above code should also not be executed. But, in fact, the second loop executes, but it's a dead loop. What is this for?
in short, do not use a floating-point number as a circular index because it causes unpredictable behavior. If you need a floating-point number in the loop, use an int or a long loop index and convert it to float or double. When you convert an int or a long to a float or double, you may lose precision, but at least it does not affect the loop itself. When you use a floating-point number, use a double instead of float, unless you are sure that float provides enough precision and that there are mandatory performance requirements forcing you to use float.
This article from "Winger" blog, declined reprint!
"Java doubts" int converted to float accuracy problem