Странное поведение Python точности с плавающей запятой для 1e-11 - PullRequest
0 голосов
/ 19 июня 2020

При использовании python, 2.7.17 или 3.6.9, возникает странное поведение при использовании значения «1e11». Для обеих версий:

>>> 1.0e-11*1.0e11

0.9999999999999999

>>> 1.0e-10*1.0e10

1.0


>>> 1.0e-12*1.0e12

1.0

>>> 1.0e-13*1.0e13

1.0

etc.

>>> 1.0-(1.0e-11*1.0e11)

1.1102230246251565e-16

В то время как для всех остальных показателей [РЕДАКТИРОВАТЬ: до 20] результат правильно равен 0,0. Очевидно, что есть некоторые проблемы с точностью с плавающей запятой, но почему это не согласовано между показателями 10, 11 и 12. Что здесь происходит?

1 Ответ

0 голосов
/ 19 июня 2020

Числа с плавающей запятой представлены в компьютерном оборудовании как дроби с основанием 2 (двоичные).

К сожалению, большинство десятичных дробей не могут быть представлены точно как двоичные дроби. Следствием этого является то, что, как правило, вводимые вами десятичные числа с плавающей запятой аппроксимируются только двоичными числами с плавающей запятой, фактически хранящимися в машине.

ваши десятичные половинные регистры округлены, вам следует рассмотреть возможность использования десятичного модуля. Между прочим, модуль decimal также предоставляет хороший способ «увидеть» точное значение, которое хранится в любом конкретном Python float

Как говорится в конце, «простых ответов нет». Тем не менее, не опасайтесь чисел с плавающей запятой! Ошибки в Python операциях с плавающей запятой наследуются от оборудования с плавающей запятой, и на большинстве машин имеют порядок не более 1 части из 2 ** 53 на операцию. Этого более чем достаточно для большинства задач, но вы должны помнить, что это не десятичная арифметика c, и что каждая операция с плавающей запятой может иметь новую ошибку округления.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...