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))

全体のプロセスは非常にスムーズです。興味深い点が 1 つあります。整数型は を処理できないことがわかってい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理論的には無制限の整数型です。固定幅型はIntInt8Int16Int32Int64および対応する unsignedWordなどですWord8

実際にIntegerは、もちろん、たとえば利用可能なメモリや内部表現によって制限されます。

デフォルトでは、GHC は GMP パッケージを使用して を表します。これは、GMP が手足の数を格納するために 32 ビット整数を使用するため、Integerバウンドがほぼ同じであることを意味します。2^(2^37)

于 2013-08-11T12:50:12.360 に答える