为什么除法会产生负数?

5
为什么这段代码输出的是负数 -147982099 而不是 8462696833 = 600851475143 / 71 的结果?
import Data.List

smallFactor n = case (elemIndex 0 (map (mod n) [2..])) of
                    Just x -> x + 2

main = print( quot n (smallFactor n) )
    where n = 600851475143

完整输出:
$ ghc --make p3; ./p3
[1 of 1] Compiling Main             ( p3.hs, p3.o )
Linking p3 ...
-147982099

2
可能是整数溢出了吗?你尝试过将smallFactor的类型更改为Integer(而不是可能会溢出的Int)吗? - user268396
此问题的重复(多年前):http://stackoverflow.com/q/20700233/3088138,http://stackoverflow.com/q/6544573/3088138。 - Lutz Lehmann
2个回答

11
因为你正在输入一个负数(假设你正在使用32位的GHC)。
where n = 600851475143 -- n = -443946297

注意:

Prelude Data.Int> 600851475143 :: Int32
-443946297

那么,Haskell如何确定要推断使用哪种整数类型,考虑到quot :: Integral a => a -> a -> asmallFactor :: Integral a => a -> Int是多态的? - user782220
1
Luqui已经回答了这个问题。如果在看了他的回答后你仍有疑问,可以随时在我们两个人的评论区再发一条评论。 - Thomas M. DuBuisson

11

在 Haskell 中,当可以自由选择整数类型时,通常默认使用 Integer。但是在这里我们看到的是 Int。原因是:

elemIndex :: Eq a => a -> [a] -> Maybe Int

Just x -> x + 2 中,x 是一个 Int,这意味着 smallFactor 必须返回一个 Int,这也意味着 nmain 中必须是一个 Int,因为 quot :: Integral a => a -> a -> a

这是使用显式类型签名的好理由。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接