В какой-то момент самое близкое представляемое значение до x + 1.0f
равно x
. После достижения этой точки из-за этой ошибки округления ваша петля не приведет к дальнейшему увеличению sum
.
В качестве иллюстрации вы можете наблюдать этот эффект, используя научную нотацию с фиксированным количеством значимых цифр. Например, с 4 значащих цифры:
0 = 0.000e0
1 = 1.000e0
2 = 2.000e0
3 = 3.000e0
...
9 = 9.000e0
10 = 1.000e1
11 = 1.100e1
...
99 = 9.900e1
100 = 1.000e2
101 = 1.010e2
...
999 = 9.990e2
1000 = 1.000e3
1001 = 1.001e3
...
9999 = 9.999e3
10000 = 1.000e4
, и если вы добавите еще один, вы должны получить 1.0001e4
, но поскольку сохранено только 4 значащих цифры, сохраненное значение равно 1.000e4
, например. 10000 + 1 = 10000 в этой системе и продолжает увеличиваться, просто повторяет этот расчет навсегда без изменения результата.
Ваш код работает точно так же, за исключением того, что float
использует двоичные числа с плавающей запятой, а не десятичные знаки, как это делает научная нотация. Но число значимых двоичных цифр по-прежнему ограничено, и при добавлении еще одного не меняет одну из этих значащих цифр, sum
перестает увеличиваться.
Это несколько сложнее, так как при двоичном, «правильным» результат на полпути между двумя представимых чисел, поэтому округление может происходить либо вниз или вверх, в этом случае вы просили добавить 1, но на самом деле получить результат 2 выше. В любом случае, как только расстояние между представляемыми значениями станет равным 4, попытка добавить его не будет иметь никакого эффекта.
Что такое i? – 7VoltCrayon
Поскольку числа с плавающей запятой являются злыми. Вы должны прочитать это: http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html – NathanOliver
Вы можете проверить максимальный доступ, используя ['std :: numeric_limits'] (http: // en.cppreference.com/w/cpp/types/numeric_limits). –