浮点列表生成器

pet*_*tik 3 floating-point haskell

可能重复:
Haskell范围和浮点数

如果我在ghci中生成一个列表,就像这样

let a = [0.1,1..10]
Run Code Online (Sandbox Code Playgroud)

这给了我一个带有以下条目的列表a

[0.1,1.0,1.9,2.8,3.6999999999999997,4.6,5.5,6.4,7.300000000000001,8.200000000000001,9.100000000000001,10.000000000000002]
Run Code Online (Sandbox Code Playgroud)

列表的最后一个元素是10.000000000000002,我假设这只是由于浮点使用.然而,与数字10相比,结果似乎不一致,例如,

last a > 10
True

last a < 10
False
Run Code Online (Sandbox Code Playgroud)

为什么列表创建不比较最终元素是否小于或等于10?

ehi*_*ird 6

根据Prelude参考实现,当值大于最终值加1/2时,浮点数的算术序列停止:

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)
Run Code Online (Sandbox Code Playgroud)

至于为什么,你必须要问委员会,但很可能他们不希望范围最终"不完整",并且认为让它有点大会不那么不直观.有浮点,它总是一个或另一个.

  • 它甚至比那更微妙 - 当元素超过两个步骤的一半时,范围会停止.试试`ghci`中的`[0.5 .. 1]`看看我的意思. (4认同)
  • 人们普遍认为(a)这是错误的决定,并且(b)不要这样做 - 使你的范围成为积分,并使用除法转换为浮点数.无论奇怪的决定如何,这都是正确的. (4认同)