Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

floating point list generator [duplicate]

Possible Duplicate:
Haskell ranges and floats

If I generate a list in ghci like so

let a = [0.1,1..10]

This gives me a list a with the following entries

[0.1,1.0,1.9,2.8,3.6999999999999997,4.6,5.5,6.4,7.300000000000001,8.200000000000001,9.100000000000001,10.000000000000002]

The last element of the list is 10.000000000000002, I assume this is just due to floating point use. However, comparing with the number 10 the result seems inconsistent, e.g,

last a > 10
True

last a < 10
False

Why is the list creation not comparing if the final element is less than or equal to the 10?

like image 726
petantik Avatar asked Apr 27 '26 11:04

petantik


1 Answers

Arithmetic sequences of floating point numbers stop when the value goes greater than the final value plus 1/2, per the reference implementation of the Prelude:

numericEnumFrom         :: (Fractional a) => a -> [a]  
numericEnumFromThen     :: (Fractional a) => a -> a -> [a]  
numericEnumFromTo       :: (Fractional a, Ord a) => a -> a -> [a]  
numericEnumFromThenTo   :: (Fractional a, Ord a) => a -> a -> a -> [a]  
numericEnumFrom         =  iterate (+1)  
numericEnumFromThen n m =  iterate (+(m-n)) n  
numericEnumFromTo n m   =  takeWhile (<= m+1/2) (numericEnumFrom n)  
numericEnumFromThenTo n n' m = takeWhile p (numericEnumFromThen n n')  
                             where  
                               p | n' >= n   = (<= m + (n'-n)/2)  
                                 | otherwise = (>= m + (n'-n)/2)

As for why, you'd have to ask the Committee, but it's likely that they didn't want a range to end up "incomplete", and thought having it a bit too large would be less unintuitive. With floating point, it's always going to be one or the other.

like image 171
ehird Avatar answered Apr 30 '26 06:04

ehird