在使用 ghci 交互式运行我的 Haskell 代码并将其加载为模块时,我得到了不同的结果



从.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 = 13481503k = 11237126m = 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 中执行此操作,都会发生这种情况;您误诊了两次测试之间的显着差异。

相关内容

  • 没有找到相关文章

最新更新