Почему sin (180) не равен нулю при использовании python и numpy?

кто-нибудь знает, почему ниже не равна 0?

import numpy as np
np.sin(np.radians(180))

или:

np.sin(np.pi)

когда я ввожу его в python, он дает мне 1.22 e-16.

2 ответов


количество π не может быть представлен точно как число с плавающей точкой. Итак,np.radians(180) не дает π, это дает вам 3.1415926535897931.

и sin(3.1415926535897931) на самом деле что-то вроде 1.22e-16.

Итак, как вы справляетесь с этим?

вы должны разработать или, по крайней мере, угадать соответствующие абсолютные и/или относительные границы ошибок, а затем вместо x == y вы пишете:

abs(y - x) < abs_bounds and abs(y-x) < rel_bounds * y

(это также означает, что вы должны организовать ваши вычисления так, чтобы относительная ошибка была больше относительно y, чем x. В вашем случае, потому что y постоянный 0, это тривиально - просто сделайте это задом наперед.)

Numpy предоставляет функцию, которая делает это для вас во всем массиве,allclose:

np.allclose(x, y, rel_bounds, abs_bounds)

(это на самом деле проверки abs(y - x) < abs_ bounds + rel_bounds * y), но это почти всегда достаточно, и вы можете легко реорганизовать свой код, когда это не так.)

в вашей дело:

np.allclose(0, np.sin(np.radians(180)), rel_bounds, abs_bounds)

Итак, как вы знаете, что правильные границы? Нет способа научить вас достаточному анализу ошибок в ответе SO. распространения неопределенности в Википедии дает обзор высокого уровня. Если у вас действительно нет подсказки, вы можете использовать значения по умолчанию, которые являются 1e-5 относительная и 1e-8 абсолютная.


проблема в том, что это не ошибка округления pi. Обратите внимание, что проблема не возникает для Косинуса:

    In [2]: np.sin(np.pi)
    Out[2]: 1.2246467991473532e-16  != 0.
    In [3]: np.cos(np.pi)
    Out[3]: -1.0                    == -1.

проблема гораздо больше ... сложный. Это связано с точностью pi внутри процессора. Это было обнаружено и объяснено здесь: https://randomascii.wordpress.com/2014/10/09/intel-underestimates-error-bounds-by-1-3-quintillion/