Turns out the accumulated error is even worse: Prelude> let old x y z = let eftt i j = i : eftt j (j+j-i) in let d = y - x in maximum $ takeWhile (<= z + d) $ eftt x y Prelude> old 0.0 0.1 86400.0 86400.0000005062 Prelude> let new x y z = let d = y - x in let go i = i : go (i + d) in maximum $ takeWhile (<= z + d) $ go x Prelude> new 0.0 0.1 86400.0 86400.00000054126
Sorry to spam the list. :-P Floating point is hard. On Tue, Aug 9, 2016 at 8:22 PM, Andrew Farmer <xicheko...@gmail.com> wrote: > Noticed this today: > > ghci> let xs = [0.0,0.1 .. 86400.0] in maximum xs > 86400.0000005062 > > enumFromThenTo is implemented by numericEnumFromThenTo: > > https://github.com/ghc/ghc/blob/a90085bd45239fffd65c01c24752a9bbcef346f1/libraries/base/GHC/Real.hs#L227 > > Which probably accumulates error in numericEnumFromThen with the (m+m-n): > > numericEnumFromThen n m = n `seq` m `seq` (n : numericEnumFromThen m (m+m-n)) > > Why not define numericEnumFromThen as: > > numericEnumFromThen n m = let d = m - n in d `seq` go d n > where go delta x = x `seq` (x : go delta (x + delta)) > > (or with BangPatterns) > > numericEnumFromThen n m = go (m - n) n > where go !delta !x = x : go delta (x + delta) > > Seems like we'd save a lot of subtractions by using the worker function. _______________________________________________ ghc-devs mailing list ghc-devs@haskell.org http://mail.haskell.org/cgi-bin/mailman/listinfo/ghc-devs