Как правило, ошибка с плавающей запятой относится к числу, которое не может быть сохранено в представлении с плавающей запятой IEEE.
Целые числа хранятся с крайним правым битом равным 1, а каждый бит слева удваивается (2,4,8, ...). Легко видеть, что здесь можно хранить любое целое число до 2 ^ n, где n - количество битов.
Мантисса (десятичная часть) числа с плавающей запятой сохраняется аналогичным образом, но перемещается слева направо, и каждый последующий бит равен половине значения предыдущего. (На самом деле это немного сложнее, но пока подойдет).
Таким образом, такие числа, как 0,5 (1/2), легко хранить, но не каждое число ‹1 может быть создано путем добавления фиксированного числа дробей вида 1/2, 1/4, 1/8, ...
Очень простой пример - 0,1 или 1/10. Это может быть сделано с помощью бесконечного ряда (что я не особо беспокоюсь о разработке), но всякий раз, когда компьютер сохраняет 0,1, сохраняется не совсем это число.
Если у вас есть доступ к Unix-машине, это легко увидеть:
Python 2.5.1 (r251:54863, Apr 15 2008, 22:57:26)
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin
Type "help", "copyright", "credits" or "license" for more information.
>>> 0.1
0.10000000000000001
>>>
Будьте очень осторожны с тестами на равенство с числами с плавающей запятой и двойными значениями на любом языке, на котором вы работаете.
(Что касается вашего примера, 0,2 - это еще одно из тех надоедливых чисел, которые нельзя сохранить в двоичном формате IEEE, но пока вы проверяете неравенства, а не равенства, например p ‹= 0,2, тогда все будет в порядке.)
person
Matthew Schinckel
schedule
30.10.2008