8

When evaluating the expression:

*main> [0, 0.1 .. 1]

I was actually expecting:

 [0, 0.1, 0.2, 0.3, 0.4, 0.5, 0.6, 0.7, 0.8, 0.9, 1]

But I was quite shocked to see the output be

[0.0,0.1,0.2,0.30000000000000004,0.4000000000000001,0.5000000000000001,0.6000000000000001,0.7000000000000001,0.8,0.9,1.0]

Why does Haskell produce that result upon evaluation?

Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Carlos
  • 5,405
  • 21
  • 68
  • 114
  • possible duplicate of [Why does ghci say that 1.1 + 1.1 + 1.1 > 3.3 is True?](http://stackoverflow.com/questions/2038647/why-does-ghci-say-that-1-1-1-1-1-1-3-3-is-true) – Gabe Feb 19 '11 at 05:04
  • @TomMD, @Avilo: Thanks for the clarification guys but I also meant that it seems a bit weird that for example 0.3....0004 and .5, .6, .7 all end in 0001 while .2, .8 and .9 are "round". It just doesn't seem consistent imprecision, i don't know if am explaining myself. – Carlos Feb 19 '11 at 05:10
  • 1
    @carlos When you learn how floating point is represented this will make perfect sense. Notice accurate values are sums of two to a negative power. – Thomas M. DuBuisson Feb 19 '11 at 05:15
  • @TomMD. Thanks buddy ill add that to the list. – Carlos Feb 19 '11 at 05:17
  • 2
    [Different question, similar answers](http://stackoverflow.com/questions/4983985/haskell-equation-solving-in-the-real-numbers/) – Dan Burton Feb 19 '11 at 06:44
  • @TomMD: two to a negative power? You mean like 0.5? – luqui Feb 19 '11 at 07:57
  • 5
    Definitely check out "What Every [Programmer](http://floating-point-gui.de)/[Computer Scientist](http://www.scribd.com/doc/5836/What-Every-Computer-Scientist-Should-Know-About-FloatingPoint-Arithmetic) Should Know about Floating Point Arithmetic." – rampion Feb 19 '11 at 14:58
  • @luqui `0.5` represents fine, it has error in Carlos's code due to starting from some approximate value (~ `0.4`) and adding `0.1`. If you're just testing single values then using the below C program is probably best as it avoids rounding before printing (I think `.17%f` is sufficient for that). – Thomas M. DuBuisson Feb 19 '11 at 16:28

2 Answers2

19

This is a result of the imprecision of floating point values, it isn't particular to Haskell. If you can't deal with the approximation inherent in floating point then you can use Rational at a high performance cost:

> import Data.Ratio
Data.Ratio> [0,1%10.. 1%1]
[0 % 1,1 % 10,1 % 5,3 % 10,2 % 5,1 % 2,3 % 5,7 % 10,4 % 5,9 % 10,1 % 1]

Just to hammer the point home, here's Python:

>>> 0.3
0.29999999999999999

And here's C:

void main() { printf("%0.17f\n",0.3); }

$ gcc t.c 2>/dev/null ; ./a.out
0.29999999999999999
Thomas M. DuBuisson
  • 64,245
  • 7
  • 109
  • 166
3

Refer to this other post. As it states, floating point numbers aren't precise in the CPU.

Community
  • 1
  • 1
Avilo
  • 1,204
  • 7
  • 7