Math.cos(Math.PI/2) 在 JavaScript 和 AS3 中返回 6.123031769111886e-17?

问题描述 投票:0回答:5

如果我理解正确的话,JavaScript 和 ActionScript 3 都可以使用弧度。

因此以下代码的预期输出将是:

Math.PI                 //Expected 3.141592653589793, got 3.141592653589793

Math.sin(0)             //Expected 0, got 0
Math.sin(Math.PI/2)     //Expected 1, got 1
Math.sin(Math.PI)       //Expected 0, got 1.2246063538223773e-16
Math.sin(Math.PI*3/2)   //Expected -1, got -1
Math.sin(Math.PI*2)     //Expected 0, got -2.4492127076447545e-16

Math.cos(0)             //Expected 1, got 1
Math.cos(Math.PI/2)     //Expected 0, got 6.123031769111886e-17
Math.cos(Math.PI)       //Expected -1, got -1
Math.cos(Math.PI*3/2)   //Expected 0, got -1.836909530733566e-16
Math.cos(Math.PI*2)     //Expected 1, got 1

这与 Firefox、Chrome、Safari 以及 Flash Professional CS5.5 中的行为相同。我使用的是 Mac OS X 10.7.2。

测试:

http://jsfiddle.net/KA4VM/

javascript flash actionscript-3 ecmascript-5
5个回答
20
投票

您是否看过您获得的价值?你期待的是 0,但你得到的是类似的东西

0.00000000000000012246063538223773

这对你来说还不够接近零吗?

基本上,当您的输入无法表示为精确的二进制值时,您不应该期望二进制浮点运算能够“完全正确”——而 pi/2 则不能,因为它是无理数。 (即使输入可以精确地用二进制表示,如果输出不能精确地表达,您也不应该期望结果是精确的......) 请注意,虽然这是用二进制浮点表示的,但十进制浮点系统也存在同样的问题:从根本上来说,如果您无法在所选类型系统中精确地表示输入/输出,则您将无法获得精确的结果算术。


3
投票
1e-15

,即

2**(-50)
左右,因此我们可以先加后减一个大小为
2**3
的数字来对结果进行四舍五入。因此,如果我们选择 8 作为数字,我们可以重新定义
sin
cos
如下:

function sin(x) { return Math.sin(x) + 8 - 8; } function cos(x) { return Math.cos(x) + 8 - 8; }

这应该可以解决错误,并且比 
toFixed

方法更快。

    


2
投票

因此,由于舍入误差,您会得到非常小的数字(您的数字是#.#####e-16 和#.#####e-17,它们很小)。

你对此无能为力,只能接受 0.000000000000000006 足够接近 0。


2
投票

Math.Sin = function(w){ return parseFloat(Math.sin(w).toFixed(10)); };

现在当你与

Math.sin(Math.PI)

这个奇怪的结果

> 1.2246467991473532e-16

你得到了你所期望的

Math.Sin(Math.PI) > 0

对其他三角函数进行同样的操作:

Math.Cos = function(w){ return parseFloat(Math.cos(w).toFixed(10)); };

等等。


1
投票

这将是 0.0000000000000001xxx(小数点后十五个零)

我打赌它足够接近零,可以将其视为 0。

由于 pi 值的误差,您会得到无穷小的误差(您应该知道,它会延伸到小数点后无限位)

你还没有提到你是在 AS3 还是 JavaScript 中得到这个

© www.soinside.com 2019 - 2024. All rights reserved.