Numerical issue with `foldl` and `foldr` in Haskell

fold, haskell

Solution

In general, the order in which floating point values are added is important. An entry point for own research could be http://en.wikipedia.org/wiki/Loss_of_significance . To summarize the basic caveat, in an oversimplified form:

Due to the limited number of significant bits, you have to assume something like

 100000000000000000.0 + 1.0 = 100000000000000000.0

in floating-point computations. Consequently, when computing

  100000000000000000.0 
+                  1.0 
- 100000000000000000.0

the result will be `0.0` - and thus, be different from

  100000000000000000.0 
- 100000000000000000.0
+                  1.0 

where the result will be `1.0`.

Problem

I have the following Haskell script which computes the function `f(x) = (2- x) - (2^3 - x^3/12)` ``` calc x = (x - (x ^ 3) / 12) calc2 x = (calc 2) - (calc x) calcList1 :: [Float] -> Float calcList1 l = foldl (+) 0.0 (map calc2 l) calcList2 :: [Float] -> Float calcList2 l = foldr (+) 0.0 (map calc2 l) test1 :: Float -> Float test1 step = (calcList1 l) - (calcList2 l) where l = [0.0,step..2.0] ``` Function `calcList1` and `calcList2` run `calc2` function on each of list and then uses `foldl` and `foldr` respectively to sum the list. I was expecting both function to return the same answer but it does not. ``` *Main> test1 0.1 9.536743e-7 *Main> test1 0.01 2.2888184e-5 *Main> test1 0.001 2.4414063e-4 *Main> test1 0.0001 -3.7109375e-2 *Main> ``` Now I am confused. I can't see why numerical issues has to be involved here. Fold are essentially how ones collect each element which should be same in both cases, right?

Original source