26

有谁知道为什么下面不等于0?

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

或者:

np.sin(np.pi)

当我将它输入 python 时,它给了我 1.22e-16。

4

5 回答 5

27

该数字π不能完全表示为浮点数。所以,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绝对的。

于 2013-09-05T22:33:49.947 回答
3

一种解决方案是在计算 sin 和 cos 时切换到 sympy,然后使用 sp.N(...) 函数切换回 numpy:

>>> # Numpy not exactly zero
>>> import numpy as np
>>> value = np.cos(np.pi/2)
6.123233995736766e-17

# Sympy workaround
>>> import sympy as sp
>>> def scos(x): return sp.N(sp.cos(x))
>>> def ssin(x): return sp.N(sp.sin(x))

>>> value = scos(sp.pi/2)
0

请记住在使用 scos 和 ssin 函数时使用 sp.pi 而不是 sp.np。

于 2019-04-19T14:34:28.127 回答
3

面临同样的问题,

import numpy as np

print(np.cos(math.radians(90)))

>> 6.123233995736766e-17

并尝试了这个,

print(np.around(np.cos(math.radians(90)), decimals=5))

>> 0

在我的情况下工作。我设置十进制 5 不会丢失太多信息。正如您可以想到的那样,轮函数在 5 位数值后去掉。

于 2019-08-07T17:41:01.253 回答
0

试试这个......它将任何低于给定微小值的东西归零......

import numpy as np

def zero_tiny(x, threshold):
    if (x.dtype == complex):
        x_real = x.real
        x_imag = x.imag
        if (np.abs(x_real) < threshold): x_real = 0
        if (np.abs(x_imag) < threshold): x_imag = 0 
        return x_real + 1j*x_imag
    else:
        return  x if (np.abs(x) > threshold) else 0

value = np.cos(np.pi/2)
print(value)
value = zero_tiny(value, 10e-10)
print(value)

value = np.exp(-1j*np.pi/2)
print(value)
value = zero_tiny(value, 10e-10)
print(value)
于 2019-04-19T16:01:27.503 回答
-2

简单的。

np.sin(np.pi).astype(int)
np.sin(np.pi/2).astype(int)
np.sin(3 * np.pi / 2).astype(int)
np.sin(2 * np.pi).astype(int)

返回

0
1
0
-1
于 2020-02-05T19:38:55.910 回答