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

发布于 2024-12-14 10:01:32 字数 915 浏览 3 评论 0原文

如果我理解正确的话,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/

If I'm understanding this correct, both JavaScript and ActionScript 3 works with radians.

So the expected output of the following codes would be:

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

This is the same behavior in Firefox, Chrome, Safari and also in Flash Professional CS5.5. I'm using Mac OS X 10.7.2.

Test:

http://jsfiddle.net/KA4VM/

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

心作怪 2024-12-21 10:01:32

你有没有看过你所获得的价值?您期望为 0,但您得到的结果是这样的:

0.00000000000000012246063538223773

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

基本上,当您的输入无法表示为精确的二进制值时,您不应该期望二进制浮点运算完全正确 - pi/2 不能,因为它是无理数。 (即使输入可以精确地用二进制表示,如果输出不能精确地表达,您也不应该期望结果是精确的......)

请注意,虽然这是用二进制浮点数表示的,但十进制浮点点系统也有同样的问题:从根本上来说,如果你不能在你选择的类型系统中精确地表达输入/输出,你就不会得到精确的算术。

Have you looked at the value you're getting? You're expecting 0, but you're getting something like

0.00000000000000012246063538223773

Isn't that close enough to zero for you?

Basically, you shouldn't expect binary floating point operations to be exactly right when your inputs can't be expressed as exact binary values - which pi/2 can't, given that it's irrational. (You shouldn't expect the results to be exact even when the inputs can be expressed exactly in binary, if the output can't be expressed exactly...)

Note that while this is expressed in terms of binary floating point, decimal floating point systems have the same problem: fundamentally, if you can't express the inputs/outputs precisely in your chosen type system, you're not going to get precise arithmetic.

变身佩奇 2024-12-21 10:01:32

考虑到这些误差都小于 1e-15,大约为 2**(-50),因此我们可以加然后减一个大小为 2 的数字**3 对结果进行四舍五入。因此,如果我们选择 8 作为数字,我们可以重新定义 sincos 如下:

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

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

这应该会消除错误,并且比 toFixed< 更快/代码> 方法。

Consider these errors are all less than 1e-15, which is around 2**(-50), so we can add then subtract a number with magnitude 2**3 to round the result. So if we pick 8 as the number, we could re-define sin and cos as following:

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

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

This should round out the error, and is faster than toFixed method.

遮云壑 2024-12-21 10:01:32

Math.PI 并不是 pi 的 100% 准确表示,仅仅是因为 pi 是无理数并且浮点数只能到此为止。

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

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

Math.PI is not a 100% accurate representation of pi, simply because pi is irrational and floating point numbers only go so far.

So due to rounding errors, you get extremely tiny numbers (your numbers are #.#####e-16 and #.#####e-17, which are tiny).

Nothing you can do about it but accept that 0.000000000000000006 is close enough to 0.

笑红尘 2024-12-21 10:01:32

因为PI是一个无理数(没有理数的实数,所以不可能计算出精确的值。
正如 Jon Skeet 所说,Math 对象的三角方法仅获取 PI 的近似值并返回近似值。
如果返回零值对您的代码很重要,则必须对它们进行舍入。
在这种情况下,为了方便起见,我通过自己的方法扩展这些 Javascript 对象:

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));
};

等等。

Because PI is an irrational number (Real Number without beeing Rational, it's impossible to calculate with exact value.
Like Jon Skeet said, the trigonometric methods of the Math-object gets only approximate values for PI and returns an approximate value.
If the return of Zero values are important for your code, you have to round them.
In cases like that I extend those Javascript objects by own methods for convenience:

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

Now while you get with

Math.sin(Math.PI)

this strange result

> 1.2246467991473532e-16

you get with what you've expected

Math.Sin(Math.PI)
> 0

Do the same with the other trigonometric functions:

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

and so on.

大海や 2024-12-21 10:01:32

所以你有 1.xxxxx * 10^-16

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

我打赌这足够接近零以将其视为 0。

由于值中的错误,你会得到无穷小的错误pi (正如你应该知道的,它延伸到小数点后无限位)

你没有提到如果你在 AS3 或不过 JavaScript

So you have 1.xxxxx * 10^-16

This would be 0.0000000000000001xxx (fifteen zeros after the decimal point)

I bet that's as close enough to zero to regard it as 0.

You get that infinitesimal error because of the error in the value of pi (as you should know, it stretches out to infinite digits after the decimal point)

You haven't mentioned if you get this in AS3 or JavaScript, though

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文