27
Hugs> 94535^445
1376320882321377050696053887661515621104890164005282153069726424773999801846841903244827702943487982707454966009456016735041878000604143500908532887464920380605164932112687039059526672109818924234920844448231612532570718657160234177285377733830104834041049076609912488237219608445995072867798430614935403219495883835042862802917980856774134757390782052200512932375660858045003581611863121089979673784484701791210379500218604466721285456487387736825167702127154268533859979529612671925052419513844416493584817268143587955662039327860394141299238613042312035808541735213479394437496215520277526351425482512084759462579494878772787079101513841720202004639843443083454387175700954018825292148776647553122504118229978165851660083576570848983047255050145168802863168613110619584686348869690774233051669081248424584219383477237544209892290799448207462345346336076966775224683516220960618177284844330167142846351091001423033864986042919757795382577032341453971393897073354841924116635150129850119992031076354249371062307034564093077675129303383786693131843907104175619570678630497198824622804914508555467550904967368926176118094672479099827962889569753303773699017596074205893197641101210911874606040804983166177455705972192827752532495287749766682029353154226049380290040508900715169403153139668217790502306177709467234413947747673881158973344492079455405942662489751581189327200960698310350121179918845099840977270519116578719881752429190273998774113278822810866144521416958558406602325070095207349450759264393913367193083149679216066539911941983836313340998945139132421885688290888674594474605510238217590823316979504437667252929278291853368754482552573193289277120902144178425726693671235675042499401282016643202758246845332593475338220708351934511933096882598943512036679145593929114103343255708217768511665236173107020739195152050863630870948954052925049746246549772984384435109578859863612603574306739909728739428192798727373799081111333186135697868385292787575475482883660605162944306327057220313320376280182432763977906971557137715710757099478269250731209785404487629107297262798803645379809868663503452656912571816192881412782623078761411808958183665272686617730596943579533808499348879195167683064937591552734375

なぜ Haskell はこれほど大きな数を計算できるのに、Java などの他の言語は (それほど簡単に) 計算できないのでしょうか?

4

8 に答える 8

45

それは設計哲学の違いです:

  • Haskell の設計者は、32 ビット以上を必要とする整数計算の一見恣意的な失敗にユーザーが驚かないようにしたいと考えていました。

  • Java の設計者は、32 ビット以上を必要とする整数に対して多くの計算を行うことによって引き起こされる一見恣意的なパフォーマンスの低下にユーザーが驚かないようにしたいと考えていました。

各言語では、別の種類の整数を取得するために特別なことを行う必要があります。

デフォルトで任意の大きな整数をサポートする言語には、長く立派な歴史があります。私のお気に入りの 2 つはIconSmalltalkで、どちらも 25 歳以上です。

于 2009-07-26T17:18:45.290 に答える
28

Java にはBigIntegerクラスがあります。

この機能を言語に組み込むこともできましたが、(多くの言語と同様に) プリミティブな機能を CPU がサポートするものに密接にマッピングする傾向があります。

一方、Haskell は数学表記のスタイルで表現力を強調しており、「パフォーマンス」の考慮事項はほとんど関係ありません。

于 2009-07-26T11:22:07.593 に答える
13

Haskell の数値リテラルはオーバーロードされているため、複数の具象型 ( IntIntegerFloatまたは などMyOwnNumber) を表すことができます。

次のように、タイプ情報を提供することで、特定のタイプを手動で選択できます。

x = 4 :: Int
y = 4 :: Integer
z = 4 :: Float

これら 3 つの値は異なる型を持ち、これらに対して実行される操作は異なる動作をします。

の正確なサイズIntは実装に依存しますが、28 ビットのようなものになる可能性があります。この型は Java プリミティブのように動作しますint。たとえば、オーバーフローします。

Anは、Java BigIntegerIntegerのように、任意精度の整数を含むことができる型です。

そして aFloatは Javafloatのようなもので、浮動小数点演算を使用します。

数値リテラルと同様に、多くの演算子も (型クラスを使用して) オーバーロードされているため、さまざまな型で使用できます。したがって、オペレーターはs とs の+両方を操作できます。IntFloat

あなたの場合、型情報を提供しなかったため、インタープリターはデフォルトでそのInteger型になります。これは、^オペレータがインスタンスも選択することを意味しIntegerます。任意精度の整数計算を可能にします。

于 2009-07-26T13:00:04.200 に答える
6

Java には「プリミティブ データ型」(プロセッサがサポートする型) の概念があり、それらは他のすべてのクラスとは異なります。

Haskell では、Intは他のすべての型と同様の型であるため、 ( )で使用されるNumおよび型クラスのメンバーにするのは簡単でした。これらの型クラスのもう 1 つのメンバーは です。これは、すべてのサイズの整数をサポートします (数字に十分なメモリがある限り)。Integral(^)"(^) :: (Num a, Integral b) => a -> b -> a"Integer

Java では、多くの「ビッグ ナンバー」ライブラリを使用できますが、それらの操作では、使い慣れた中置演算子は使用されません。これは、Java の「プリミティブ型」専用であるためです。

于 2009-07-26T11:41:09.567 に答える
3

短くて基本的な答えは、デフォルトの整数の違いを実装することです。Java では、標準の int は 32 ビットです。署名済み、それはあなたに の範囲を与え−2,147,483,648ます+2,147,483,647

とはいえ、Java にもbignumクラスがあります。それらを使用すると、任意に大きな数を使用する能力も得られます。

于 2009-07-26T11:20:44.210 に答える
1

すでに述べたように、32 ビット ワードを使用して全範囲を使用すると、2 の補数を使用して -2^31 から 2^31-1 になります。

ワードの数ビットを予約することにより、それらのビットを使用して値の型情報を運ぶことができます。つまり、値は実行時に独自の型を「認識」します。残りのビットは、値のデータを運ぶために使用されます。

これらの残りのビットに収まる整数値は、ワードに直接格納できます。このような整数は通常「fixnums」と呼ばれます。それらが収まらない場合、単語の型ビットはそれが「bigint」であることを示し、残りのビットは、bigint 値が格納されているヒープにメモリ ポインタを格納するために使用されます。

コンパイラは、演算式を複数のコード パスに変換して、オペランドに許可されている型の組み合わせをカバーする必要があります。追加の例:

  • fixnum + fixnum
  • bigint + fixnum
  • fixnum + bigint
  • bigint + bigint

これらの言語のコンパイラでの最適化の多くは、これを機能させるために必要な実行時の型チェックのオーバーヘッドを回避することに重点を置いています。多くの場合、fixnum から bignum への自動降格は望ましくなく、代わりに 32 ビット整数のオーバーフロー動作が必要であることをコンパイラに明示的に伝える方法もあります。これは、暗号化アルゴリズムを効率的に実装するために非常に重要です。

于 2009-07-26T12:44:38.033 に答える
0

数字をどのようにエンコードするかの問題です。これを行う従来の方法は、指定されたビット数で数値をエンコードすることであり、無限の精度を実現することはできません。Haskell は数値の可変ビット数を使用してこれを行っているようですが、これは通常、すべての計算がソフトウェアで行われることを意味します。ハードウェア アクセラレーションは通常、有限の精度でしか利用できないためです。

于 2009-07-26T11:21:59.513 に答える
0

BigInteger を使用して同じことを行うことができます。Haskell は Java よりも簡潔な関数型言語です。

非常に多くの言語が存在する理由の 1 つは、異なる言語は異なる前提で設計されているため、異なるタスクでより優れているからです。ほとんどの関数型言語は、数学関数を使用するとより単純になりますが、他のユース ケースでは苦労する傾向があります。

于 2009-07-26T11:22:16.127 に答える