Javascript的几何方法:零不完全为零,是吗?

Elf*_*erg 4 javascript floating-point geometry

在用Javascript和Canvas编写的简单几何程序中,当我将角度设置为270°(1½π)时,我期望Math.cos(θ)变为零.矢量从中心向下直线,笛卡尔网格上没有x距离.相反,我明白了:

demo_angle = 270
ang = demo_angle * Math.PI / 180
x = Math.cos(ang) 
console.log(x)
> -1.836909530733566e-16
Run Code Online (Sandbox Code Playgroud)

要查看数学函数的输出,请查看控制台.源代码在URL中可见(在coffeescript中)一级.

我必须在我的代码中定义"绝对值小于1e-15的任何数字应该被认为是零",但这确实不令人满意.毋庸置疑,当我尝试使用x小的值进行数学运算时,特别是因为我试图x在斜率计算中使用分母然后进行一些二次操作,我最终得出的数字超过了Number.MAX_VALUE(或Number.MIN_VALUE).

我知道浮点数学在汇编语言层面上是一种黑暗艺术,但是这样的结果似乎比可接受的更奇怪.关于我应该做什么的任何暗示?

Ste*_*non 9

问题不在于"零不完全为零".相反,零正好为零.

您遇到的问题是3π/ 2不能表示为浮点数.所以你实际上取的值的余弦不等于3π/ 2.这种表示错误有多大?大约1.8e-16,这是您在余弦中看到的错误的来源.

有些语言通过提供类似的函数来解决这个问题,sinpi并且cospi隐式地将它们的参数按比例缩放π; 这是提供精确结果的一种方法.显然,这不是你的选择,因为javascript没有这样的功能.如果你愿意,你可以自己动手,利用这些功能的对称性,或者你可以简单地将"接近零"的值钳制到零,就像你现在一样.两者都不是特别令人满意,但两者都可能适用于您的目的.