使用python和numpy时为什么sin(180)不为零?

MCF*_*MCF 14 python trigonometry numpy

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

import numpy as np
np.sin(np.radians(180))
Run Code Online (Sandbox Code Playgroud)

要么:

np.sin(np.pi)
Run Code Online (Sandbox Code Playgroud)

当我进入python它给我1.22e-16.

aba*_*ert 15

该数字?不能完全表示为浮点数.所以,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
Run Code Online (Sandbox Code Playgroud)

(这也意味着你要组织你的计算,使相对误差相对较大y,而不是x在你的情况,因为y是恒定的0,这是微不足道的,只是做了落后的.)

Numpy提供了一个函数,可以在整个数组中为您执行此操作allclose:

np.allclose(x, y, rel_bounds, abs_bounds)
Run Code Online (Sandbox Code Playgroud)

(这实际上是检查abs(y - x) < abs_ bounds + rel_bounds * y),但这几乎总是足够的,并且您可以轻松地重新组织代码.)

在你的情况下:

np.allclose(0, np.sin(np.radians(180)), rel_bounds, abs_bounds)
Run Code Online (Sandbox Code Playgroud)

那么,你怎么知道正确的界限是什么?在SO答案中没有办法教你足够的错误分析.维基百科的不确定性传播给出了高级概述.如果你真的没有线索,可以使用默认值,即1e-5相对值和1e-8绝对值.

  • 我实际上对错误分析有很好的了解,所以这非常有用. (2认同)
  • 这个特定位置的误差几乎与np.radians(180)中的误差完全相同.该错误可能是大约0.5到1.0 ULP(最后一个单位),或大约3.14*DBL_EPSILON,或大约7e-16.我的误差估计是最坏情况估计,因此实际误差稍微小一点并不奇怪.请参阅这篇文章了解血淋淋的细节(以及对这个结果真正非常酷的一些想法):https://randomascii.wordpress.com/2014/10/09/intel-underestimates-error-bounds-by-1-3 -quintillion / (2认同)