1

这是一段非常简单的代码。它接受一个整数并使用商和余数分解其十进制数字。在每次调用时,它打印一行包含 r 个字符“I”,其中 r 是最后一个数字,然后使用商作为其新参数调用自身。

decToUnary 0 = return ()
decToUnary n = let (q, r) = quotRem n 10 in 
    do  
      putStrLn (take r "IIIIIIIIII")
      decToUnary q

它适用于少于 10 位的数字,但对于 10 位或更多位的数字,它会打乱输出。我做错了什么,为什么会这样?以下是一些输出示例,第一个是正确的,第二个是错误的:

*Main> decToUnary 5432
II
III
IIII
IIIII

*Main> decToUnary 5432101234
IIIIIIII
III
IIIIIIIII
III
III
I
IIIIIII
III
I
I
4

1 回答 1

13

这是一个整数溢出问题。maxBound :: Int是 2147483647(在 32 位机器上),所以值大于溢出。

使用Integer代替Int:Integer不是固定长度的整数,因此它不会溢出。

编辑:作为应用说明,您将需要take r "IIIIIIIIII"take (fromIntegral r) "IIIIIIIIII"or替换genericTake r "IIIIIIIIII"; 我宁愿genericReplicate r 'I'.

genericTake并且genericReplicate都在 Data.List 中。

于 2013-03-01T19:37:12.087 回答