客户坚持认为sin(Math.PI)和cos(Math.PI / 2)应该返回零,而不是10 ^ -16左右。他对Math.sin()和Math.cos()就是这样的解释不满意,这不仅适用于Javascript,而且适用于所有其他语言。

我发现的一件事是Math.sin()对小于2e-16的参数更改不敏感:

Math.sin(Math.PI)
1.2246063538223773e-16
Math.sin(Math.PI + 1e-16)
1.2246063538223773e-16
Math.sin(Math.PI + 2e-16)
1.2246063538223773e-16
Math.sin(Math.PI + 3e-16)
-3.216285744678249e-16


因为当sin(x)接近零时sin(x)〜= x,所以我有义务在x小于2e-16时将sin(x)强制为零。

Math.cos()更精确,它对高达1.1e16的更改不敏感(编辑:它发生是因为基值更小:Math.PI / 2),因此当cos(x)小于时,我会将其转换为零。 1e-16:

Math.cos(Math.PI / 2)
6.123031769111886e-17
Math.cos(Math.PI / 2 + 1e-16)
6.123031769111886e-17
Math.cos(Math.PI / 2 + 1.1e-16)
6.123031769111886e-17
Math.cos(Math.PI / 2 + 1.5e-16)
-1.6081428723391245e-16


当然,当x-> 0时,这种强制转换会破坏sin(x)的原始精度:

Math.sin(1e-99)
1e-99
Math.sin(1e-50)
1e-50
Math.sin(1e-40)
1e-40
Math.sin(1e-20)
1e-20
Math.sin(1e-10)
1e-10
Math.sin(1e-5)
0.000009999999999833334


但是,如果应用程序使用的是这么小的角度,应该直接使用x,而不是sin(x),对吗?由于sin(x)在此范围内趋于x。

考虑到该应用程序的UI精度为10位,您觉得我的策略正确吗?

最佳答案

您可以决定要返回零的接近程度-

Number.prototype.rounded= function(i){
    i= Math.pow(10, i || 15);
    // default
    return Math.round(this*i)/i;
}
Math.sin(Math.PI).rounded()
/*  returned value: (Number) 0 */

Math.PI.rounded(5)
/*  returned value: (Number) 3.14159 */

关于javascript - Javascript sin()和cos()的有效解决方案?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/21741246/

10-13 08:53