从.hs文件加载的代码:
modPow :: Int -> Int -> Int -> Int
modPow a k m = (a^2 `mod` m)^(k `div` 2)
以交互方式输入的代码:
(13481503^2 `mod` 46340)^(11237126 `div` 2)
即a = 13481503
、k = 11237126
、m = 46340
前者在具有相同值的 ghci 中调用时返回一个完全不同的数字,即modPow 13481503 11237126 46340
查看您使用的表达式类型:
> :t (13481503^2 `mod` 46340)^(11237126 `div` 2)
(13481503^2 `mod` 46340)^(11237126 `div` 2) :: Integral a => a
当强制计算类型 Integral a => a
的值时,ghci
默认为 Integer
(就像交互式解释器对 show
的隐式调用一样),而您的函数返回一个 Int
。
您将modPow
定义为Int -> Int -> Int -> Int
,即它接受并返回Int
s(64位整数),因此所有操作都是模64位。
手动执行表达式时,GHCI 会将数字向上转换为 Integer
(大小不受限制),从而生成正确的输出。
你正在将某些东西提高到 5,618,563 的幂。这是一个巨大的数字。可以用 Int
表示的最大数字(假设它是有符号的 64 位整数)是 (2 ^ 63) - 1
。由于 5,618,563> 63,任何增加到 500 万次方的东西都不适合Int
(除非"任何东西"是 1、0 或 -1)。所以modPow :: Int -> Int -> Int -> Int
会溢出
在没有类型签名的情况下输入相同的操作将默认为 Integer
,这不限于 64 位的方式Int
。因此,计算不会溢出,并会给出真实的结果。无论您是在模块中还是在 GHCi 中执行此操作,都会发生这种情况;您误诊了两次测试之间的显着差异。