最高の(ポータブルな)クロスプラットフォームの任意精度の数学ライブラリは何ですか?[閉まっている]


81

CまたはC ++で適切な任意精度の数学ライブラリを探しています。アドバイスや提案をお願いします。

主な要件:

  1. これは、必要があります任意の大きな整数を、私の扱う主要な関心は整数です。任意に大きいという言葉が何を意味するのかわからない場合は、100000のようなものを想像してください!(100000の階乗)。

  2. ライブラリの初期化またはオブジェクトの作成中に精度を指定する必要はありません。精度は、システムの利用可能なリソースによってのみ制約される必要があります。

  3. それはすべきプラットフォームのフルパワーを利用し、ネイティブで「小さな」の数字を処理する必要があります。つまり、64ビットプラットフォームでは、(2 ^ 33 + 2 ^ 32)の計算には使用可能な64ビットCPU命令を使用する必要があります。ライブラリ、同じプラットフォームで(2 ^ 66 + 2 ^ 65)を使用する場合と同じ方法でこれを計算するべきではありません

  4. それは必要があり、効率的付加をハンドル(+)、減算(-)、乗算(*)、整数除算(/)、残り(%)、電源(**)、インクリメント(++)、デクリメント(--)、GCD、階乗、及び他の一般的な算術計算整数。整数の結果を生成しない平方根や対数などの関数を処理する機能はプラスです。記号計算を処理する機能はさらに優れています。

これが私がこれまでに見つけたものです:

  1. JavaBigIntegerクラスとBigDecimalクラス:私はこれまでこれらを使用してきました。ソースコードを読みましたが、その下の計算がわかりません。それは私が学んだことのない理論やアルゴリズムに基づいているのかもしれません。

  2. 組み込みの整数型またはbcPythonRubyHaskellLispErlangOCamlPHP、その他の言語のコアライブラリ:これらのいくつかを使用しましたが、どのライブラリを使用しているかわかりません。彼らが使用している実装の種類。

私がすでに知っていること:

  1. 使用するchar小数点以下の桁用とchar*進文字列のため、および使用して数字上の計算を行うfor-loopを。

  2. int(または、、long intまたはlong long)を基本的な「単位」として使用し、そのタイプの配列を任意の長整数として使用し、for-loopを使用して要素の計算を行います。

  3. 整数型を使用して、10進数(または数桁)をBCD(2進化10進数)として格納します。

  4. ブースの乗算アルゴリズム

私が知らないこと:

  1. 単純な方法を使用せずに、上記のバイナリ配列を10進数で出力します。単純な方法の例:(1)ビットを最低から最高に追加します:char*1、2、4、8、16、32 、…(2)上記の-文字列を使用して中間の小数の結果を格納します)。

私が感謝すること:

  1. GMPMPFRdecNumber(またはあなたの意見で良い他のライブラリ)の良い比較。

  2. 私が読むべき本や記事に関する良い提案。たとえば、ナイーブでない2進化10進変換アルゴリズムがどのように機能するかを示す図があればよいでしょう。ダグラス・W・ジョーンズによる「限られた精度での2進化から10進への変換」という記事は良い記事の例です。

  3. 一般的なヘルプ。

(または、、または)を使用するとこの問題を簡単に解決できると思われる場合は、この質問に答えないでください。そう思うと、問題の問題を理解できません。doublelong doublelong long double


3
私が見る限り、GMPは優れたライブラリのようです。私が疑問に思うのは、Python / Haskell / Erlang /などの貢献者が車輪の再発明をする必要がある理由です。GMPが非常に優れているのなら、なぜそれに頼らないのですか?GPL / LGPLライセンスが問題の1つである可能性がありますが、これ(および丸めモードの問題)にもかかわらず、GMPの他の欠点はありますか?Python / Haskell / Erlang /暗号化ライブラリの組み込み整数はGMPよりも高速ですか?もしそうなら、ライセンスが許せば、それを抽出して使用したいと思います。
Siu Ching Pong -Asuka Kenji- 2010

Douglas W.Jonesによるcs.uiowa.edu/~jones/bcd/decimal.htmlで素敵な記事を見つけました。この記事では、8ビット整数演算のみを使用して16ビット整数を10進表現に変換する方法について説明します。アイデアは、16ビットの数値を4つのニブルに分割し、それぞれが基数16の「桁」を表すことです。したがって、数字0(n0)はx1、n1 => x16、n2 => x256、n3 => x4096を表します。すると、10進数(d0)の0桁がn0 * 1 + n1 * 6 + n2 * 6 + n3 * 6の結果の0桁であることは明らかです。キャリーを適切に処理することにより、d1からd4は次のことができます。また、計算されます。
Siu Ching Pong -Asuka Kenji- 2010

しかし、私が想像できる限り、上記のダグラスのアイデアは、任意の長さの2進整数を処理するように拡張することはできませんでした。これは、数値1(16 ^ 0)、16(16 ^ 1)、256(16 ^ 2)、および4096(16 ^ 3)が事前に計算されているためです。問題は、任意の大きさのnに対して16 ^ nを10進数で表す方法になります。
Siu Ching Pong -Asuka Kenji- 2010

回答:


24

GMPは人気のある選択肢です。Squeak Smalltalkには非常に優れたライブラリがありますが、Smalltalkで記述されています。

あなたは関連する本や記事を求めました。bignumのトリッキーな部分は、筆算です。パー・ブリンチ・ハンセンの論文「Multiple-Length Division Revisited:A Tour oftheMinefield」をお勧めします。


論文へのリンクありがとうございます!はい、私は除算が最も難しい部分であることに同意します。私は昔、「紙と鉛筆の方法」を使って手で分割する方法を知っていました:-)したがって、同じ方法をchar *(それぞれcharが10進数を表す)の10進int *文字列またはBCD文字列(それぞれがint4/8 / 16BCD桁を表します)。ただし、実際の本番レベルのライブラリは、速度が遅すぎるため、「紙と鉛筆の方法」を模倣しているのではないかと思います。
Siu Ching Pong -Asuka Kenji- 2010

理由を理解するために、それがどのように実行されるかを想像してみましょう100,000,000,000,000,000 / 333,333,333,333。最初のステップは、と比較100,000,000,000すること333,333,333,333です。前者は後者よりも小さいため、計算は単に次の桁に移動します。第二段階は、商を見つけることで1,000,000,000,000 / 333,333,333,333、このいずれかの試行錯誤の乗算を含む、333,333,333,333 * 1(および* 2* 3および* 4)、またはループ内の連続減算を行います。どれだけ遅いかわかりますか?より効率的なアルゴリズムが存在すると思います。
Siu Ching Pong -Asuka Kenji- 2010

3
@Sui:ブリンチ・ハンソンは、試行錯誤の方法を最大2回の試行に減らす方法を示しています。とても印象的です。
ノーマンラムゼー

さて、私は紙をもっと詳しく見てみましょう。ありがとうございました!
Siu Ching Pong -Asuka Kenji- 2010

1
どこで解決策を見つけたのか、また数字を格納するために使用した形式もわかりませんが、COBOLのCOMP-3ニブル形式はよりコンパクトで、各4ビットが0〜9を格納するため、処理がはるかに優れています。値、および、使用可能な桁を取得するためにASCII文字値から16進数30を減算する必要はありません。

13

全体として、彼の最速の汎用任意精度ライブラリはGMPです。浮動小数点値を操作する場合は、MPFRライブラリを参照してください。MPFRはGMPに基づいています。

他の言語でのネイティブの任意精度のサポートに関して、Pythonは、ライセンス、コードサイズ、およびコードの移植性の理由から、独自の実装を使用します。GMPYのモジュールは、GMPライブラリPythonのアクセスをすることができます。


ご回答ありがとうございます!「コードの移植性」についておっしゃいました。何が問題なのか説明してもらえますか?GMPは移植性があり、主要なプラットフォームでサポートされていると思いました...
Siu Ching Pong -Asuka Kenji- 2010

2
「コードの移植性」は「主要なプラットフォームでサポートされている」と同じではありません。Pythonは、Cコンパイラーの動作についてほとんど想定しない単純な実装を使用しているため、ほとんどすべてのCコンパイラーで同じコードをコンパイルできます。GMPは、GMPを高速化するだけでなく、Cコンパイラーとアセンブラーの動作についてより多くの仮定を行う、より多くのコード(Cおよび高度に調整されたアセンブリー)を使用します。たとえば、GMPはMicrosoft VisualStudioコンパイラでは十分にサポートされていません。MicrosoftのコンパイラをサポートするMPIR(www.mpir.org)と呼ばれるGMPフォークがあります。
casevh 2010

そうですか。つまり、Pythonの実装はANSI Cに似ていますが、GMPの実装は__asmトリックを使用しています...説明ありがとうございます。
Siu Ching Pong -Asuka Kenji- 2010

8

TTMathを参照してください。これは、個人用および商用用に無料でテンプレート化された小さなヘッダー専用ライブラリです。


ねえ!これは使いやすいライブラリであり、CPUパワーを利用しているようで、C ++テンプレートの魔法を使用してジョブを完了します。素晴らしい図書館!あなたのために+1!
Siu Ching Pong -Asuka Kenji- 2013

ええ、そしてそれは寛容な非コピーレフトBSDライセンスを持っています。
プラズマセル2018年

上記のページから:「値の大きさはコンパイル時に設定されます。」-したがって、これは要件に適合しません。
osxdirk


4

何についての巴里?これはトップGMPに基づいて構築されており、必要となる数論演算(および多くの記号計算関連)に関する他のすべての優れた機能を提供します。


こんにちはFortran(!)、よさそうです!情報をくれてありがとう!
Siu Ching Pong -Asuka Kenji- 2010年

どういたしまして:-)また、Pariを使用すると、GPを使用して高速のプロトタイプを作成でき、満足のいくときに最適化されたCバージョンを作成できます(GP-> Cコンパイラーも付属していると思います)
fortran
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.