2009-07-26 20 views
26
Hugs> 94535^445 
1376320882321377050696053887661515621104890164005282153069726424773999801846841903244827702943487982707454966009456016735041878000604143500908532887464920380605164932112687039059526672109818924234920844448231612532570718657160234177285377733830104834041049076609912488237219608445995072867798430614935403219495883835042862802917980856774134757390782052200512932375660858045003581611863121089979673784484701791210379500218604466721285456487387736825167702127154268533859979529612671925052419513844416493584817268143587955662039327860394141299238613042312035808541735213479394437496215520277526351425482512084759462579494878772787079101513841720202004639843443083454387175700954018825292148776647553122504118229978165851660083576570848983047255050145168802863168613110619584686348869690774233051669081248424584219383477237544209892290799448207462345346336076966775224683516220960618177284844330167142846351091001423033864986042919757795382577032341453971393897073354841924116635150129850119992031076354249371062307034564093077675129303383786693131843907104175619570678630497198824622804914508555467550904967368926176118094672479099827962889569753303773699017596074205893197641101210911874606040804983166177455705972192827752532495287749766682029353154226049380290040508900715169403153139668217790502306177709467234413947747673881158973344492079455405942662489751581189327200960698310350121179918845099840977270519116578719881752429190273998774113278822810866144521416958558406602325070095207349450759264393913367193083149679216066539911941983836313340998945139132421885688290888674594474605510238217590823316979504437667252929278291853368754482552573193289277120902144178425726693671235675042499401282016643202758246845332593475338220708351934511933096882598943512036679145593929114103343255708217768511665236173107020739195152050863630870948954052925049746246549772984384435109578859863612603574306739909728739428192798727373799081111333186135697868385292787575475482883660605162944306327057220313320376280182432763977906971557137715710757099478269250731209785404487629107297262798803645379809868663503452656912571816192881412782623078761411808958183665272686617730596943579533808499348879195167683064937591552734375 

ハスケルはなぜこのような大きな数を計算でき、Javaなどの他の言語は(簡単に)できないのですか?なぜHaskellは非常に大きな数を簡単に処理できますか?

答えて

25

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

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

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

+20

しかし、明らかにしておきますが、Haskellの開発者は一般的にパフォーマンスの問題を無関係とみなしません。 – amindfv

+0

私は同意します - 私はHaskellのアプローチをサポートしているので、 "パフォーマンス"の周りに引用符を入れます。 –

+1

現実のHaskellコードでは、Intが使用されます。整数はJavaでBigIntegerを使用する場合にのみ使用されます。実際には違いはありませんが、Haskellでは型を指定しないとIntegerがデフォルトの型です。 (タイプが指定されていなければ、とにかくプロダクションコードではないと正しく仮定されているので) – Evi1M4chine

3

簡単で基本的な答えは、デフォルトの整数の差異を実装することです。 Javaでは、標準intは32ビットです。署名して、−2,147,483,648から+2,147,483,647の範囲を指定します。

つまり、Javaにはbignumクラスもあります。これらを使用すると、任意に大きな数値を使用することもできます。

0

数字をエンコードする方法の問題です。これを行う伝統的な方法は、無限の精度を持つことができないビット数で数値をエンコードすることです。ハスケルは、明らかにこれを行うには、ビット数を変えることもできますが、ハードウェアアクセラレーションは一般に有限精度でしか利用できないため、すべての計算がソフトウェアで行われることを意味します。

+1

私は、HaskellがLispのように円滑な範囲チェックと数値変換を提供すると推測します。数字がfixnumの範囲内にある限り、計算はマシン上で正常に直接実行されますが、オーバーフローはbignumへの変換によって検出され除去されます。 – Svante

+1

@Svante:いいえ、それはまったく真実ではありません。ハスケルは、どんな型の間でも自動的な変換を持たず、Intsの範囲チェックをもたない。あいまいなタイプの問題です。 Haskellの整数リテラルは、インスタンスNumの任意の型に型指定できます。ここでは型があいまいです。デフォルトでは、Haskellのデフォルト値はIntegerです。ここで説明します:http://www.haskell.org/onlinereport/decls.html#default-decls – newacct

+1

@newacct:Haskellレポートは整数の振る舞いを定義していますが、それは意味しません彼らはfixnumsとbignumsとして実装することはできません。実際にこれを行うHaskell実装があるかどうかはわかりませんが、 –

0

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

私たちが非常に多くの言語を持っている理由の1つは、異なる前提で設計されているため、異なる言語が異なるタスクで優れているということです。ほとんどの関数型言語は数学関数では単純ですが、他の使用例と闘う傾向があります。 haskellはGUIを書くのに適しているとは思えません。

+1

とghcjsは今や素晴らしい選択です! – Fresheyeball

6

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

Intは、他のすべてのタイプのようなタイプであるため、容易に(^)"(^) :: (Num a, Integral b) => a -> b -> a")で使用NumIntegral型クラスのメンバーを作製しました。これらのタイプメーターの別のメンバーはIntegerです。これは、すべてのサイズの整数をサポートしています(数字のための十分なメモリがある限り)。

Javaでは、多くの「Big Numbers」ライブラリを使用できますが、それらの操作ではJavaの「プリミティブ型」のみであるため、使用している中置演算子は使用されません。

+1

これを正しく理解しているかどうかを確認してください。したがって、Haskellの^演算子は特定の型に直接バインドされていませんが、ある意味では同じように動作する型の "カテゴリ"(またはそのような2つのカテゴリのようです) Haskellは、実行時に式を与える型を選択しますが、常に同じカテゴリ内で指定しますか?ポスターの例のように、94535^445の結果は整数型を表現する必要がありますが、3^5の結果は表現するIntで行うことができます。 – harms

+4

@harms:Haskellは、コンパイル時に型推論と型チェックを行います。この場合、型情報は提供されないので、デフォルトは 'Integer'(Javaの' BigNumber'のようなもの)になります。しかし、型情報を手動で追加して数値が 'Int'(Javaプリミティブ' int'のように)であると言うと、 '^'演算の結果が単にオーバーフローし、不正な 'Int'結果が生成されます。 –

1

すでに言及したように、32ビットワードを使用し、フルレンジを使用すると、2^31から2^31-1の2の補数を使用します。

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

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

コンパイラは、算術式を複数のコードパスに変換する必要があります。添加のための例:

  • FIXNUM + FIXNUM
  • BIGINT + FIXNUM
  • FIXNUM + BIGINT
  • BIGINT + BIGINT

これらの言語のコンパイラにおける最適化の多くはオーバーヘッドを回避に焦点を当てますこの作業を行うために必要な実行時型チェックのために。 fixnumからbignumへの自動降格が望ましくないことを明示的にコンパイラに伝える方法もありますが、代わりに32ビット整数のオーバーフロー動作が必要です。これは、暗号アルゴリズムを効率的に実装する上で非常に重要です。彼らは(IntIntegerFloatあるいはMyOwnNumberなど)複数の具体的なタイプを表すことができるようにハスケルで

+0

多態性に伴うランタイムオーバーヘッドは必ずしもありません。そのための例としてHaskellを使用します。また、JavaやHaskellのどちらもそれを使用しているとは思わないので、予約ビット全体がどのようにこの質問に関連しているかわかりません。 – yairchu

+0

最適化できれば、ランタイムオーバーヘッドはありません。 Haskell(少なくともGHC)は、オーバーフロー時にbigintegersへのフィックスナンバーの自動昇格を行います(Integer型の場合)。そのjavaは、なぜプリミティブintまたはIntegerがオーバーフローするのか説明しません。bigintを使用し、値がfixnumの範囲に収まる場合でもコストを取る必要があります。 – Christian

10

数値リテラルは、オーバーロードされています。

は、手動でそのような種類の情報を提供することで、特定のタイプを選ぶことができます:

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

これらの三つの値が異なる動作をしますこれらに対して実行さまざまな種類と事業を展開しています。

Intの正確なサイズは実装に依存しますが、28ビットのようなものでもよく、このタイプはJavaプリミティブintのように動作します。それはオーバーフローします。

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

そして、Floatは、浮動小数点演算を使用するJava floatのようなものです。

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

あなたのケースでは、タイプ情報を入力していないため、通訳者はデフォルトでIntegerタイプになります。つまり、^演算子の場合は、Integerインスタンスも選択されます。任意精度の整数計算を可能にする。

42

それは設計思想で違いです:

  • ハスケルのデザイナーは、ユーザーが32ビット以上を必要とする整数計算の一見任意の失敗によって驚かないようにしてくださいになりたかったです。

  • Javaの設計者は、32ビット以上の整数を必要とする多くの計算を実行することによるユーザのパフォーマンスの低下を驚かせることを望んでいました。

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

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

+10

ハスケルの「何か特別なもの」はちょっと簡単ですが、それはあなたの型として 'Int32'を使うことを意味しますが、Javaでは演算子のオーバーロードがないと' x (y) 'または' x.multiply(y) ' –

+2

コモンLisp ftw:D –

+0

ええ、私は"特別なもの "はハスケルにとって非常に不公平だと思う。 Haskellではbounded intをJavaのbound intと同じ量だけ使用できます。 'int x = 5'と' x = 5 :: Int'です。 – semicolon

関連する問題