我正在处理一个函数,该函数将数字中的所有数字相加,并保持累加数字直到数字减少到一位数。例如,应该像这样评估数字99999999999
:
99999999999
9+9+9+9+9+9+9+9+9+9+9
99
9+9
18
1+8
9
但是,当我尝试通过我的函数运行数字99999999999
时,它会返回7
,即使它应该返回9
。我已经多次查看了我的代码,我想不出任何理由。
以下是代码:
sumdr x
| x <= 9 = x
| otherwise = sumdr $ addupnums x
addupnums y = foldl (+) 0 $ map read1 $ show y
read1 :: Char -> Int
read1 '1' = 1
read1 '2' = 2
read1 '3' = 3
read1 '4' = 4
read1 '5' = 5
read1 '6' = 6
read1 '7' = 7
read1 '8' = 8
read1 '9' = 9
read1 '0' = 0
read1 x = error "needs to be a number"
答案 0 :(得分:6)
这对我来说在64位系统上运行正常。如果您使用的是32位系统,则99999999999不适合Int,因此它会溢出并给您错误的结果。
如果将类型更改为Integer,则应该可以正常工作。
答案 1 :(得分:2)
<强> [编辑] 强>
如果你只对重复申请的结果感兴趣,直到剩下一个数字,当然Daniel Fischer是对的,你应该使用他的解决方案。如果不可能有这样的捷径,如何处理这类问题仍然是有益的,因此我留下了我的旧答案。
<强> [/编辑] 强>
你得到了答案,但有两个评论:
digitToInt
中找到Data.Char
函数,这是read1
f 0 = 0
f y = (y `mod` 10) + f (y `div` 10)
或稍微神秘的版本:
f = sum . map (`mod` 10) . takeWhile (> 0) . iterate (`div` 10)
如果你真的关心速度,你可以使用divMod
,你可以试试累加器是否更快,例如。
f n = go n 0 where
go 0 s = s
go k s = go k' (s+s') where (k',s') = k `divMod` 10