我正在解决数学问题:想要得到数字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
。我们怎么能解释这个以及Haskell Integer
的上限或限制是什么?
答案 0 :(得分:11)
在Haskell中,Integer
是理论上 - 无界的整数类型。固定宽度类型包括Int
,Int8
,Int16
,Int32
,Int64
以及相应的无符号Word
,Word8
等
实际上,即使Integer
当然也可以通过可用内存或内部表示来限制。
默认情况下,GHC使用GMP包来表示Integer
,这意味着绑定是2^(2^37)
左右,因为GMP使用32位整数来存储肢数。
答案 1 :(得分:-1)
Integer
在Haskell中没有上限;它是一个无界的整数类型。 Haskell中的Integer
与Java中的BigInteger
类似,Java中的Integer
与Haskell中的Int
类似。 Haskell中的Int
在[-2 ^ 63,2 ^ 63]处有界限。