Это связано с тем, что числа с плавающей запятой неточны и находятся в двоичном виде . Но я хочу продемонстрировать, как это работает.
Проблема в том, что десятичное число, такое как 0,135, не может быть представлено точно. Что касается представления с плавающей запятой, оно обычно будет выглядеть примерно так:
0.134999999234243423
(Обратите внимание, что эти числа, как и все представления значений в этом ответе, составлены. Они предназначены для того, чтобы представлять.)
Количество 9
с на самом деле больше. И последующие цифры являются просто представительными. В этом представлении мы не увидим проблемы с усечением значения. Ведь 0.1349999
должно округляться до того же значения, что и 0.13499
.
В двоичном виде это выглядит иначе:
0.11101000010101 10011 10011 10011 10011 . . .
---------------- --------------
~0.135 "arbitrary" repeating pattern
(Примечание: значения составлены!)
То есть «бесконечная» часть двоичного представления не является группой повторяющихся 1
с или повторяющихся 0
с;у этого есть образец. Это аналогично обратному большинству чисел в базе 10. Например, 1/7
имеет повторяющийся компонент из шести цифр, 142857
. Мы склонны забывать об этом, потому что общие инверсии либо точны (1/5 = 0,2), либо имеют одну повторяющуюся цифру (1/6 = 0,166666 ...). 1/7
- это первый случай, который не так прост - и почти все десятичные дроби такие. Для рациональных чисел существует всегда повторяющаяся последовательность независимо от основания, и она никогда не длиннее, чем делимое (число внизу) минус 1).
Мы можем думать об этом как обо всех десятичных числахпредставления (независимо от базы) всегда имеют некоторое количество повторяющихся цифр. Для точного представления повторяющаяся часть равна 0
. Для других это редко одна цифра. Обычно это несколько цифр. И это забавное упражнение по математике, чтобы охарактеризовать это. Но все, что важно, это то, что повторяющаяся часть имеет 1
с и 0
с.
Теперь, что происходит. Число с плавающей запятой состоит из трех частей:
- величина. Это число битов, представляющих показатель степени.
- целочисленная часть, которая является числом до десятичной точки.
- целочисленная часть, которая является числом после десятичной точки.
(На самом деле, последние два действительно одно целое число, но мне проще объяснить это, разделив их на два компонента.)
Доступно только фиксированное количество битдля двух целочисленных частей. Как это выглядит? Еще раз репрезентативные шаблоны выглядят примерно так:
0.135 0 11101000010101100111001110
1.135 1 11101000010101100111001110
2.135 10 1110100001010110011100111
4.135 100 111010000101011001110011
8.135 1000 11101000010101100111001
16.136 10000 1110100001010110011100
-----------^ part before the decimal
------------------^ part after the decimal
Примечание: это исключает часть величины десятичного представления.
Как видите, цифры отсекаются отконец. Но иногда отрубается 0
- поэтому в представляемом значении нет изменений. И иногда это 1
. И есть изменение.
С этим вы можете увидеть, как значения существенно колеблются, скажем:
0.135 --> 0.135000000004
1.135 --> 0.135000000004
2.135 --> 0.135000000004
4.135 --> 0.135000000001
8.135 --> 0.135999999997
16.135 --> 0.135999999994
Затем они округляются по-разному, что вы и видите.
Я собрал эту маленькую db <> скрипку , чтобы вы могли видеть, как округление изменяется вокруг степеней двух.