2017-03-16 39 views
1

我發現了一些基於二進制對數(log base 2)計算估計的代碼中的一個奇怪的錯誤。下面是lb的代碼,其中計算一個正整數的二進制數:意外的行爲與權力2

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^30lb

+1

您是否嘗試將'Int'切換爲'Integer'?我認爲這可能是一個下溢問題。我認爲默認是'Integer',所以第三個lambda應該可以工作... – Dair

+0

啊,我忘了鍵入約束測試值。是的,那應該解決它。 –

回答

4

交換機的身體IntInteger。基本上,你正在創建一個很大的Int,它溢出。 Integer是任意精度。 (注意:在不同的體系結構中,數字可能有所不同,我的電腦在63而不是31)失敗。

+0

我使用Integral來保持它的一般性,但是效果很好 –