1

我正在解决一个数学问题:想要得到数字的数字之和2^1000

在 Java 中,解决方案如下:

String temp = BigInteger.ONE.shiftLeft(1000).toString();

int sum = 0;
for (int i = 0; i < temp.length(); i++)
    sum += temp.charAt(i) - '0';

然后在 Haskell 中提出了一个解决方案,如下所示:

digitSum ::(Integral a) => a -> a                  
digitSum 0 = 0
digitSum n = (mod n 10) + (digitSum (div n 10))

整个过程还算顺利,有一点看起来很有趣,我们知道整数类型不能处理2 ^ 1000,太大了,在Java中,很明显BigInteger将大数字使用和处理为字符串,但在Haskell中,没有编译错误意味着2 ^ 1000可以通过直接进去。事情是这样的,Haskell 是否在内部将数字转换为字符串?我想确定类型是什么并让编译器确定,然后我在GHCi中键入以下行:

Prelude> let i = 2 ^ 1000

Prelude> i 
107150860718626732094842504906000181056140481170553360744375038837035105112493612249319
837881569585812759467291755314682518714528569231404359845775746985748039345677748242309
854210746050623711418779541821530464749835819412673987675591655439460770629145711964776
86542167660429831652624386837205668069376

Prelude> :t i
i :: Integer

在这里,我完全糊涂了,显然,数i量过大,但返回类型 i 仍然是Integer. Integer我们如何解释这一点以及Haskell的上限或限制是什么?

4

1 回答 1

13

在 Haskell 中,Integer是一种 - 理论上 - 无界整数类型。固定宽度类型有Int, Int8, Int16, Int32,Int64以及对应的 unsignedWordWord8

在实践中,evenInteger当然是有界​​的,例如可用内存或内部表示。

默认情况下,GHC 使用 GMP 包来表示Integer,这意味着边界是2^(2^37)左右,因为 GMP 使用 32 位整数来存储肢体的数量。

于 2013-08-11T12:50:12.360 回答