为什么Int类型2 ^ 31不超出GHCi的范围?

时间:2014-11-13 22:33:11

标签: haskell ghci hugs

我正在阅读Programming in Haskell书籍并测试GHCi口译员提供的示例。事实证明,GHCi和Hugs解释器中的Int类型行为存在差异。根据" Haskel编程"的第3章,2^31 :: Int应该超出Int类型的范围。同时,在GHCi翻译中我得到:

Prelude> 2^31 :: Int
2147483648
在Hugs中,它的表现就像书中所说的那样:

Hugs> 2^31 :: Int
-2147483648

在GHCi中,我甚至可以检查结果是否为Int

的类型
Prelude> let x = 2^31 :: Int
Prelude> :type x
x :: Int
Prelude> x
2147483648

所述差异的来源是什么?我应该从Hugs中的书中运行示例还是使用GHCi,这似乎是学习Haskell的推荐选择?我将非常感谢你的帮助。

3 个答案:

答案 0 :(得分:20)

Haskell中的Int必须支持至少范围[-2^29 .. 2^29-1],但它也可以更大。确切的大小取决于您使用的编译器和您所使用的架构。 (您可以在2010 Haskell Report中了解更多相关信息,这是Haskell语言的最新标准。)

在64位计算机上使用GHC,您将获得[-2^63..2^63 - 1]的范围。但即使在32位机器上,我相信GHC给你的范围会比严格的最小值(大概是[-2^31..2^31 - 1])大一点。

您可以查看maxBoundminBound的实际界限:

> maxBound :: Int
9223372036854775807

实现之间的差异出现了,因为语言定义显式允许它们以不同的方式实现这些类型。就个人而言,我会继续使用GHCi只记住这一点,因为GHC是目前最有可能使用的编译器。如果你遇到更多的不一致,你可以在标准中查找它们或者询问某人(就像这里一样!);把它想象成一种学习经历;)。

该标准在这方面非常灵活,允许不同的编译器和体系结构以不同方式优化其代码。我假设(但不是100%肯定)最小范围是考虑到32位系统,同时也让编译器使用底层32位值中的几个位用于其内部目的,如易于区分指针中的数字。 (我知道Python和OCaml的东西,至少要这样做。)GHC不需要这样做,所以它暴露了适合其架构的完整32或64位。

答案 1 :(得分:4)

很可能你是64位系统,其中Int有64位。

试试这个:

Prelude> 2^62::Int
4611686018427387904
Prelude> 2^63::Int
-9223372036854775808

答案 2 :(得分:4)

Int是机器大小的。所以在32位平台上它会在2 31 上溢出。

$ ssh pi@192.168.0.3
Linux raspberrypi 3.12.28+ #709 PREEMPT Mon Sep 8 15:28:00 BST 2014 armv6l

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Tue Nov 11 12:58:20 2014 from 192.168.0.102
pi@raspberrypi:~$ ghci
GHCi, version 7.8.2: http://www.haskell.org/ghc/  :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> 2^31 :: Int
-2147483648

请注意,Haskell报告确实没有指明Int应该有多大,正如Tikhon Jelvis所说,它只能保证处理2 29 。但GHC肯定会使用所有机器整数,这通常是非常优化的性能和需求。