Reputation: 923
JavaScript Math trigonometrical methods return wrong results.
alert(Math.sin(Math.PI));
// sin(180) in degrees should return 0, but above code doesn't
it doesn't return 0.
Maybe problem is with JavaScript decimal number precision. Is there any workaround to get correct results?
Upvotes: 22
Views: 10373
Reputation: 161
This is actually not a bug, and not even a rounding error from Math.sin
itself.
Mathematics says sin(π) = 0
. but Math.PI
is only an approximation of π, so, mathematically, sin(Math.PI)
is not zero. The value is also pretty clearly not a denormal, so it's not unexpected to get a non-zero value.
In fact, as the derivative of sin near π is around -1, we can estimate that sin(x) ≈ π - x
(this is effectively an iteration of Newton's method). Substituting Math.PI
, we obtain π ≈ Math.PI + sin(Math.PI) ≈ Math.PI + Math.sin(Math.PI)
.
Indeed:
> Math.PI.toString(16)
'3.243f6a8885a3'
> Math.sin(Math.PI).toString(16)
'0.00000000000008d313198a2e038'
(I'm using hexadecimal because floats aren't precisely formatted when using decimal)
The sum of these two numbers when computed by hand is 3.243f6a8885a308d313198a2e038, or, converted to decimal, 3.14159265358979323846264338327950587... This approximation of π is valid for 33 decimal digits, as opposed to the 17-digit approximation provided by Math.PI
-- almost doubling the precision. Of course, you can't actually work with such a number in JS's builtin floats, but there are tricks such as double-double arithmetic.
Anyway: Math.sin
is, in fact, extremely accurate -- it's Math.PI
that introduces the error!
Upvotes: 1
Reputation: 57
you can use
Math.sin(Math.PI).toFixed(3) // "0.000"
const cos = (a) => Math.cos(Math.PI * a / 180);
cos(90) // 6.123233995736766e-17
then you can use .toFixed()
cos(90).toFixed(3) // "0.000"
.toFixed()
returns string, so you can parse it to float using parseFloat()
parseFloat(cos(90).toFixed(3)) // 0.000
Upvotes: 4
Reputation: 32586
It's very, very close to zero, though. (~ 10^-16)
And alert(Math.sin(Math.PI/2))
does return 1
.
It's just one of things you have to be careful of when dealing with floating point arithmetic. Rounding errors pop up all over the place.
Upvotes: 16