Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Haskell sine and cosine functions not working

Okay, this is a pretty weird problem.

The built-in Haskell sine function (sin) does not seem to work.

sin 0 gives, correctly, 0.

sin pi gives, for whatever reason, 1.2246467991473532e-16

These are using the built in prelude functions. I simply start up ghci (the Haskell interpreter), and type in sin pi and get the wrong answer.

Also, cos (pi/2) gives 6.123233995736766e-17

Any ideas why this might be? It looks like the build in functions are simply wrong.. which seems extremely unlikely seeing how mathematically-oriented the Haskell standard library is.

edit: Heh, I just simply overlooked the e-16.. I guess that's what I get for coding late at night. Thanks anyhow everyone!

like image 681
Nathan Avatar asked Nov 29 '22 01:11

Nathan


1 Answers

This is Matlab

>> sin(pi)
ans =
  1.2246e-016

And here's Python

>>> from math import sin, pi
>>> sin(pi)
1.2246467991473532e-16

You're running into the limits of floating point precision. I recommend having a read of What Every Computer Scientist Should Know About Floating Point Arithmetic.


The e at the end of these numbers indicates that they're in (a compact form of) scientific notation, and stands for "× 10^". For instance, in this notation, 2e3 corresponds to 2 × 103 = 2000. Here, you have a number that's multiplied by 10-16, which is tiny; written out in full, 1.2246467991473532e-16 = 0.00000000000000012246467991473532, so the amount of error is very small.


If you want accurate real-number computations in Haskell, you can use the CReal package as follows.

>>> import Data.Number.CReal
>>> sin (0.0  :: CReal)
0.0
>>> sin (pi   :: CReal)
0.0
>>> cos (pi/2 :: CReal)
0.0

This works because "under the hood" a CReal is a function Int -> Integer. Given a number of digits d to output, the function produces the Integer that, when divided by 10^d, would give the real number correct to d decimal places.

like image 141
Chris Taylor Avatar answered Dec 05 '22 04:12

Chris Taylor