我在一些代码中发现了一个奇怪的错误,我根据二进制对数(log base 2)计算了估算值。以下是lb
的代码,它计算正整数的二进制对数:
lb :: Int -> Maybe Int -- Binary logarithm, rounded down
lb 1 = Just 0
lb x
| 1 < x = (+1) <$> lb (div x 2)
| otherwise = Nothing
这是错误,如下面带注释的ghci输出
所示λ: lb (2^30)
Just 30
λ: lb (2^31) -- should be Just 31
Nothing
λ: 1 < 2^31 -- smoke check, lb's first guard evaluates to True
True
λ: lb (div (2^31) 2) == lb (2^30) -- smoke check, these should be equal
False
λ: div (2^31) 2 == 2^30 -- smoke check, these are indeed equal
True
似乎lb (2^31)
以某种方式失败了第一个守卫,导致otherwise
表达,但我找不到原因的一致解释。
此外,似乎表达式div (2^31) 2
在某种程度上没有与2^30
lb
评估相同的内容
答案 0 :(得分:4)
从Int
切换到Integer
。基本上,您创建的Int
非常大,以至于溢出。 Integer
是任意精度。
(注意:在不同的架构上,数量可能会有所不同。我的计算机在63
而非31
处失败。