Ответ 1
Это связано с тем, что float
имеет минимальную точность, которая может быть представлена, что уменьшилось по мере увеличения значения float
. Где-то между 2 ^ 24 и 2 ^ 25 добавление одного уже недостаточно, чтобы изменить значение на следующее наибольшее представимое число. В этот момент, каждый раз через цикл, f
просто сохраняет одно и то же значение, так как f += 1.0f
больше не изменяет его.
Если вы измените свой цикл на это:
while(true) {
float newF = f + 1.0f;
if(newF == f) System.out.println(newF);
f += 1.0f;
if (f >= number) {
System.out.println(f);
System.out.println(number + " took " + (System.currentTimeMillis() - startTime) + " msecs");
break;
}
}
Вы можете видеть это. Кажется, что он перестает расти, как только f
достигает 2 ^ 24.
Вывод вышеуказанного кода будет бесконечным числом "1.6777216E7", если вы запустите его с помощью 2 ^ 25.
Вы можете проверить это значение с помощью функции Math.nextAfter
, которая сообщает вам следующее отображаемое значение. Если вы попытаетесь запустить этот код:
float value = (float)Math.pow(2.0, 24.0);
System.out.println(Math.nextAfter(value, Float.MAX_VALUE) - value);
вы можете видеть, что следующее представимое значение после 2 ^ 24 равно 2 ^ 24 + 2.
Для отличной разбивки того, почему это происходит, и почему это начинает иметь значение там, где это происходит, см. этот ответ