Javascript sin()和cos()的有效解决方案?

Javascript sin()和cos()的有效解决方案?,javascript,math,Javascript,Math,客户坚持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 + 2

客户坚持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)~=x,当sin(x)接近零时,我想到当x小于2e-16时,将sin(x)转换为零

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

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:

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


考虑到应用程序具有10位数的UI精度,您认为我的策略正确吗?

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

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 */

一个客户坚持“得到一个更好的客户,最好是那些对浮点数学有一定了解的客户。”。客户是否也要求
.1+.2==.3
?“因为sin(x)~=x,当sin(x)接近零时”-错误。当x接近零时,它是-的。@epx看看是否有help@p.s.w.g除了JavaScript之外,所有的有效点在逻辑上都是正确的,你不认为
0.1+0.2=0.3
——现在,一个不熟悉复杂的JS浮点操作的客户也会这么认为。他也不在乎是什么让应用程序滴答作响——JS还是小妖精magic@Igor对不起,我的意思是x模180度,还有信号反转,所以它们在绝对值上接近于+1,计算机处理像
π
这样的数字时只能近似,即
数学。π
不等于
π
,所以
sin(Math.PI)
已经不同于
sin(π)
。这个答案可以让您更好地了解计算中的计算机错误有多大。如果客户希望以符号方式解决问题,您只能真正使用恒等式,或许还可以使用整数加法、减法和乘法。