Как лучше всего справиться с этой числовой ошибкой Python? - PullRequest
2 голосов
/ 02 января 2012

У меня есть этот код, который выдает math domain error исключение:

v = -1.0

for i in range (201):
    print acos (v)
    v += 0.01

Но если я изменю его на это, он будет работать:

v = -100

for i in range (201):
    print acos (v / 100.0)
    v += 1

Это из-за округления?

Как лучше всего решить это в Python?Или я должен просто сделать это, как мой последний пример?

Ответы [ 2 ]

8 голосов
/ 02 января 2012

Если вы делаете:

>>> format(0.01, '.30f')
'0.010000000000000000208166817117'

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

Итак, при суммировании 100 раз ошибка увеличивается:

>>> sum([0.01]*100)
1.0000000000000007

И этого достаточно, чтобы выдать ошибку математического домена.

Что вы можете сделать?

  • Используйте второй код
  • round() это меньше десятичных знаков:

.

>>> round(1.0000000000000007, 13)
1.0

13 или 14 может быть достаточно.

1 голос
/ 02 января 2012

Вы можете попробовать это:

v = -1.0
for i in range(201):
    print acos(v)
    v = round(v + 0.01, 2)

Это будет работать на ваш вопрос. Это та же самая старая проблема с числами с плавающей запятой: не все десятичные числа могут быть точно представлены в двоичном виде. Запустите это:

v = -1.0
for i in range(201):
    print repr(v), acos(v)
    v += 0.01

И вы увидите, что в конце цикла, прямо перед ошибкой, v имеет значение, немного большее, чем 1.0, и , что является причиной math domain error.

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