Haskell 如何编译大数?

How does Haskell compile the large numbers?

我只想知道它在编译时是如何工作的。 GHC 作为其解释器,使用 GMP 库来生成和操作非常大的数字,但是 GHC 编译的可执行文件没有第三方 GMP 库可以携带。那么编译器如何保持相同的准确性呢?可执行文件是否有自己的大量操作实现?

GHC 编译的可执行文件使用 GMP 实现 Integer

an executable compiled by GHC does not have a third-party GMP library to carry

如果您的意思是 GHC 编译的可执行文件不 link 反对 GMP,那您就错了。他们有。

如果你参加这个项目:

main :: IO ()
main = do
  x <- readLn :: IO Integer
  print $ x + 1

并在带有 -v 标志的 Linux 机器上编译它:

$ ghc -v AddOne.hs

然后您会在详细输出的末尾找到用于 link 可执行文件的 gcc 命令:

*** Linker:
gcc -fno-stack-protector -DTABLES_NEXT_TO_CODE '-fuse-ld=gold' ...

这是一条很长的线,但如果你搜索它,你应该会找到(可能接近尾声)一组正在 linked 的外部库:

...  -lHSrts -lCffi -lgmp -lm -lrt -ldl -lpthread

GMP 库中 -lgmp linking。

您也可以使用ldd命令来显示可执行文件中存在对系统GMP库的依赖:

$ ldd AddOne
...
        libgmp.so.10 => /usr/lib/x86_64-linux-gnu/libgmp.so.10 (0x00007fc0da1fa000)
...

至少,在我的系统上,最新版本的 GHC 运行 在 Stack 下就是这种情况。如果您发现在您的系统上没有 GMP 依赖项,这可能只是因为事情已被配置为将所需的 GMP 代码静态 link 到可执行文件中,而不是在运行时动态 linking。 (例如,我认为在 Windows 上,GMP 代码默认是静态 linked。)

为了使事情稍微复杂一些,可以使用 integer library other than GMP,尽管这需要在编译 GHC 本身时完成。 link 中提到的一个替代方案是 integer-simple 库,它是作为 GHC 源代码树的一部分的大整数运算的 Haskell 实现。因此,在那种特定情况下,可执行文件将使用自己的大量操作实现。不过,我认为您不太可能找到使用 GMP 以外的东西的标准预编译 GHC。