【问题标题】:Why does .NET Math.Cos() return a wrong answer for pi/2? [duplicate]为什么 .NET Math.Cos() 会为 pi/2 返回错误的答案? [复制]
【发布时间】:2020-05-22 21:08:51
【问题描述】:

我有一种将度数转换为弧度的方法...

public static double ToRadians(double degAngle) 
{
    return Math.PI * degAngle / 180;
}

...而且效果很好。 但是当我尝试 Math.Cos(ToRadians(90));,它返回 6.12303176911189E-17。为什么会这样?

【问题讨论】:

  • 你注意到E-17了吗?那是因为四舍五入。浮点数没有无限精度。
  • 期望值是多少?它有多远?它是否在预期的浮点不精度范围内? youtube.com/watch?v=PZRI1IfStY0
  • cos(90 degrees) 的期望值为0(余弦是单位圆的 X 分量,在九十度处为零)。您得到的答案是由于浮点精度错误。 6E-17 非常接近于零。
  • 这是基于documentation 的预期结果,同样的事情发生在other language。我假设您永远不能将 90 度传递给该方法,因为它需要以弧度作为参数非常精确。

标签: c# .net math trigonometry


【解决方案1】:

这不是因为您没有将 pi/2 作为参数传递,而是因为它接近它。

Math.PI * 90 / 180 不会返回 90 度的精确弧度,只会返回非常接近的值,因为 Math.PI 没有无限精度。要获得 Math.Cos 返回的精确值 0,您需要以弧度传递精确值。你只能得到一个非常接近零的值。 documentation 表明这是正确的值。

【讨论】:

  • 我仍然得到相同的答案。还是我使用了错误的值? 90度的准确值不是1.5707963267948966192313216916916398... 的弧度吗?
  • @AllisonE 您无法获得 90 度的精确弧度值。只有在您的评论中非常接近的东西。这就是结果非常接近于零的原因。
  • @AllisonE 需要无限位数才能完美地以弧度表示 90 度,因为 PI 本身就是超越的。
【解决方案2】:

90 度是 大约 1.5707963267948966... 弧度。我说“大约”是因为 PI 是一个超越数,但在双精度浮点值中,我们仅限于 64 位。这意味着结果计算将存在一定的误差。当您取余弦(超越函数)时,同样的错误再次发生。结果值不能以双精度完美表示,因此您会收到一个近似值。正确答案为零。您的答案是0.00000000000000061230317691118863非常接近于零。

如果您手动计算,使用3.14 作为 PI 的值,您将得到一个接近但不完全为零的答案,原因相同:您使用的是近似值。使用 3.1415926 会给你一个更接近的答案,但 PI 的值仍然是一个近似值。计算机正在使用另一种近似值,一个限制为 64 位精度,得出大约 16 位 PI。

在任何使用 IEEE-754 浮点数学的计算系统中都会出现此问题。请参阅Is floating point math broken? 了解更多信息。

还可以查看this blog post,其中更详细地介绍了 PI 在计算机中的表示方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-01-20
    • 1970-01-01
    • 2020-12-01
    • 2016-01-03
    相关资源
    最近更新 更多