How would the following code behave, especially when the double counter reaches its limit ((2-2^-52)·2^1023)?
for (double i = 0; i < Double.POSITIVE_INFINITY; i++){
//do something
}
Would this code behave as expected (loop forever) or fail at some point and why?
Thanks.
解决方案
This code will never exit the loop.
The reason for this is that adding 1 to a sufficiently large double number does not change its value:
double a = 1.7976931348623155E308;
double old = a;
a++;
System.out.println(a); // prints 1.7976931348623155E308
System.out.println(old); // prints 1.7976931348623155E308
System.out.println(a==old); // prints "true"
In fact, when the value of double gets sufficiently close to positive infinity, you need to add a number well above 10200 in order to make your large double change value and become POSITIVE_INFINITY.
The reason for this is the way double represents large numbers. It uses a short mantissa to represent the most significant digits of the value, and an exponent to indicate where the fractional point should be placed. In case of very large numbers, the exponent is essentially an indication of how many zeros need to be added after the binary representation of the mantissa.
In order to make your double number change value through addition, you need to add a number that is at least as large as the least significant bit of the mantissa. Once the binary exponent goes above 48, the smallest number that you need to add in order for the result to be different becomes 2, meaning that ++ would no longer change the value.