为什么 math.cos(math.pi/2) 不返回零?

Mic*_* M. 2 python floating-point pi trigonometry

我遇到了一些奇怪的行为math.cos()(Python 3.11.0):

>>> import math
>>> math.cos(math.pi)  # expected to get -1
-1.0
>>> math.cos(math.pi/2)  # expected to get 0
6.123233995736766e-17
Run Code Online (Sandbox Code Playgroud)

我怀疑浮点数学可能在其中发挥作用,但我不确定如何发挥作用。如果确实如此,我会假设 Python 只是检查参数是否等于math.pi/2开始。

我找到了Jon Skeet 的答案,他说:

基本上,当您的输入无法表示为精确的二进制值时,您不应该期望二进制浮点运算完全正确 - pi/2 不能,因为它是无理数。

但如果这是真的,那么math.cos(math.pi)也不应该起作用,因为它也使用math.pi近似值。math.pi/2我的问题是:为什么这个问题只有在使用时才会出现?

chu*_*ica 6

与 \xcf\x80中的任何错误math.pi(总是有一些)在一种情况下几乎没有什么区别math.cos(math.pi),而在math.cos(math.pi/2).

\n
\n

曲线是平坦的

\n

math.cos(x)非常接近 1.0 时,曲线非常平坦:斜率“接近”零。\xcf\x80 附近大约有4700 万个浮点值在数学上大于 -1.0,但它们的值比下一个可编码值 -0.99999999999999988897 更接近 -1.0...xcos(x)

\n

曲线的斜率为 1

\n

x接近 \xcf\x80 且math.cos(x/2)接近 0.0 时,余弦曲线具有|斜率| “接近”一。下一个更小的和下一个更大的可编码x都有不同的cos(x/2).

\n

结论

\n

当|结果| 的值sin(x), cos(x)接近 1.0,许多附近的x值将报告 1.0。

\n

即使某个x值非常接近 \xcf\x80,情况也是如此。

\n

对于x接近 \xcf\x80 (如math.pi)和y = |cos(x)|,我们需要大约两倍的精度y才能看到 中的不精确性x

\n