Python中为什么np.sin(np.pi)的结果不为0?
import numpy as np
print(np.sin(np.pi))
print(np.sin(0.5*np.pi))
结果分别是
1.2246467991473532e-16
1.0
Python中为什么np.sin(np.pi)的结果不为0?
这是浮点数精度导致的常见问题。np.pi 是π的近似值,np.sin() 计算时会产生微小的浮点误差。
import numpy as np
result = np.sin(np.pi)
print(f"np.sin(np.pi) = {result}") # 输出约 1.2246467991473532e-16
print(f"是否接近0: {np.isclose(result, 0)}") # 输出 True
实际值约 1.22e-16,非常接近0。这是IEEE 754浮点数标准的固有特性,所有编程语言都会遇到。
处理建议:
- 比较时用容差:
np.isclose(a, b)或abs(a - b) < 1e-10 - 需要精确0时取整:
np.round(np.sin(np.pi), 12)
总结:用容差比较替代精确相等。
因为π不能用有限空间的浮点数表示,只是一个近似值,所以你只能得到一个很接近 0 的值,而不是 0
同理 tan(π/2)
这叫 Catastrophic Cancellation
这也是比较浮点数时不能用==的原因
至于为什么第二个可以输出 1.0,是因为前面的 1.0000…占据了有效数字位(双精度可以保证 15~16 个有效数字),使误差被舍去了
#2 又查了下资料发现 Catastrophic Cancellation 好像不是这个意思。。
因为 Numpy 主打数值计算,精度误差不可避免。希望 sin(pi) 是精确值可以考虑 Mathematica 或者 SymPy:
In [1]: import sympy
In [2]: sympy.pi
Out[2]: pi
In [3]: sympy.sin
Out[3]: sin
In [4]: sympy.sin(sympy.pi)
Out[4]: 0
至于为什么 pi/2 更准:
In [1]: 1.0 == 1.0
Out[1]: True
In [2]: 1.0 == 1.0+1e-16
Out[2]: True
In [3]: 1.0 == 1.0+1e-15
Out[3]: False
In [4]: 1.0 == 1.0+1e-16
Out[4]: True
In [5]: 1.0 == 1.0+1.2e-16
Out[5]: False
具体代码可以去查查
https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/ieee754/dbl-64/s_sin.c;hb=HEAD#l281
do_sin 函数里似乎用了麦克劳林级数。所以返回的都是近似值。

