.NET BigIntegerが何のために設計されているかを正確に述べているドキュメントはありますか?


12

私は.NET BigIntegerをいじっていますが、基本的には(予測される答えは問題ないでしょう) の曲線の偏差点((操作に必要な時間の増加)と(BigIntegerの値))?

または、1から無限へのBigIntegerの値と操作に必要な時間の増加をプロットすると、滑らかな曲線になるように、そのような偏差なしで設計されていますか?

たとえば、配列が50個のアイテムを処理できるように設計されていると仮定します。つまり、アイテムが1つある場合、操作はf(1)時間です。そして、私が2つのアイテムを持っているとき、操作はf(2)時間です。50個のアイテムがある場合、操作はf(50)時間です。ただし、50個のアイテムのみを処理するように設計されているため、51個のアイテムがある場合に実行される操作はg(51)で、g(51)> f(51)です。

適切に実装された場合、BigInteger演算の複雑さは滑らかな曲線になります。たとえば、乗算の時間計算量はO(NM)で、Nは最初の被乗数の桁数、Mは2番目の被乗数の桁数です。もちろん、数値がマシンに収まらないほど大きいNとMを選択できるという点で実用的な制限があります。

それがそのように実装されていると主張するドキュメントを知っていますか?


3
@Down有権者、下票は、質問が良い質問ではない理由を説明するコメントを残せなければ意味がありません。私はそれに問題がないと思うので、これを支持しました。
マフィンマン

私は下票しませんでしたが、ここで何が問題なのかわかりません。bigintの操作(加算、乗算、除算など)のランタイム/メモリの複雑さを知りたいですか?
ニキエ

たとえば、配列が50個のアイテムを処理できるように設計されていると仮定します。これは、アイテムが1つあり、操作がf(1)時間である場合を意味します。そして、私が2つのアイテムを持っているとき、操作はf(2)時間です。50個のアイテムがある場合、操作はf(50)時間です。ただし、50個のアイテムのみを処理するように設計されているため、51個のアイテムがある場合に実行される操作はg(51)で、g(51)> f(51)
Pacerier

@Charles E. Grant yes!これが私が話していることです。質問はありますか/それがそのように実装されていると主張する文書を知っていますか?
Pacerier

@Paceierコメントを回答に移動し、これを正確に説明するドキュメントへのリンクを追加しました。
チャールズE.グラント

回答:


7

ULong.MaxValueよりも大きい、またはLong.MinValueよりも小さい可能性のある数値は、BigIntegerを使用して表現する必要があります。

NOT(Long.MinValue <= X <= ULong.MaxValue)Then BigInteger

BigIntegerは、通常のプリミティブが処理できる数よりも大きい数値用です。

たとえば、整数がLongの範囲外の場合、おそらくBigIntegerを使用する必要があります。ただし、これらのケースは非常にまれであり、これらのクラスを使用すると、対応するプリミティブよりもオーバーヘッドが大幅に高くなります。

たとえば、long64ビット幅で、-9,223,372,036,854,775,808から9,223,372,036,854,775,80の範囲を保持できます。ulongは、0〜18,446,744,073,709,551,615を保持できます。数値がそれより大きいか小さい場合、BigIntegerが唯一のオプションです

実際のアプリケーションで使用されているのを見たのは、でんぷんを塗るアプリケーションだけでした。

関連項目:.NETのプリミティブ範囲


もちろん、可能な限り通常のプリミティブを使用する必要があることを知っています..たとえば、BigIntegerはULong.MaxValueの100倍大きい数値用に設計されているのか、BigIntegerはULong.MaxValueの100k倍大きい数値用に設計されているのですか?ULong.MaxValueの100k倍のサイズをサポートできることはわかっていますが、この範囲を念頭に置いて設計されていますか、または「範囲外の要件」と宣言されたこの範囲で設計されていますか?
-Pacerier

5
BigIntegerを使用しないと、ULong.MaxValueよりも大きい数値を表すことはできません。そのためです。ULong.MaxValueより大きくなる可能性のある数値は、BigIntegerである必要があります。
マルフィスト

もちろん、BigIntegerを使用せずに、ULong.MaxValueより大きい数を表す方法があります。ULongとブール値とビオラで構成されるカスタム構造を簡単に書くことができます。ULong.MaxValueの最大2倍を表すことができます
Pacerier

はい。ただし、BigIntegerを使用する方がはるかに複雑ではありません。おそらく、たとえ高速であっても、それほど高速ではなく、BigIntegerほど柔軟ではないでしょう。ブール値の配列を使用して非常に大きな数を表すこともできますが、それはあまりにも複雑です。
マルフィスト

2
@Mavrik、彼はこれを私が答えたものとは全く異なる質問に変えました。
マルフィスト

4

ある意味では、BigIntegerのポイントは絶対サイズではなく、精度に制限はありません。浮動小数点数も非常に大きくなりますが、精度は制限されます。BigIntegerを使用すると、丸めエラーやオーバーフローを気にせずに算術演算を実行できます。あなたが支払う代償は、通常の整数や浮動小数点数を使った算術よりも数百倍遅いということです。

他の人が指摘したように、ulongは0〜18,446,744,073,709,551,615を保持でき、その範囲内にいる限り正確な算術を実行できます。その範囲を1つでも超えるとオーバーフローが発生するため、正確な算術演算が必要で、中間結果が18,446,744,073,709,551,615を超える可能性がある場合、質問の答えはBigIntegerを使用します。

科学、工学、金融のほとんどの問題は、浮動小数点数によって強制される近似値に耐えることができ、BigInteger演算の時間コストを払うことはできません。ほとんどの商用計算は、浮動小数点演算の近似値では生きられませんが、0〜18,446,744,073,709,551,615の範囲内で機能するため、通常の演算を使用できます。BigIntegerは、暗号化(50桁の素数など)を含む数論のアルゴリズムを使用する場合に必要です。また、正確な計算が必要な場合、速度がそれほど重要ではなく、適切な固定小数点システムをセットアップするのが面倒な場合に、商用アプリケーションで使用されることもあります。

適切に実装された場合、BigInteger演算の複雑さは滑らかな曲線になります。たとえば、乗算の時間計算量はO(NM)で、Nは最初の被乗数の桁数、Mは2番目の被乗数の桁数です。もちろん、数値がマシンに収まらないほど大きいNとMを選択できるという点で実用的な制限があります。

「bigintegerの計算の複雑さ」をグーグルで検索すると、棒を振るよりも多くの参照を取得できます。あなたの質問に直接答えるのは、これです:2つの任意精度の算術パッケージの比較


4

メモリ制限

BigIntegerは、ストレージとしてint配列に依存しています。これを想定すると、BigIntegerが表現できる最大数の理論上の制限は、.netで使用可能な最大配列サイズから導出できます。ここに配列に関するSOトピックがあります:C#で配列に割り当てることができるメモリ量を見つける

最大配列サイズを知っていると仮定すると、BigIntegerが表すことができる最大数を推定できます:(2 ^ 32)^ max_array_size、ここで:

  • 2 ^ 32-配列セルの最大数(int)
  • max_array_size-2GBのオブジェクトサイズによって制限されるint配列の最大許容サイズ

これにより、6億桁の10進数の数字が得られます。

パフォーマンス制限

パフォーマンスに関しては、BigIntegerは乗算にKaratsubaアルゴリズムを使用し、加算に線形アルゴリズムを使用します。乗算の複雑度はです3 * n ^ 1.585。つまり、大きな数値でもかなりうまくスケーリングできますが(複雑度グラフ)、RAMとプロセッサキャッシュのサイズによってはパフォーマンスが低下する可能性があります。

最大数のサイズが2GBに制限されている限り、降下マシンでは予期しないパフォーマンスギャップは見られませんが、それでも6億桁の数字での操作は非常に遅くなります。


これは素晴らしい情報ですが、BigIntegerがint配列に依存しているソースはどこですか?
-Pacerier

dotPeekを使用して.netソースを掘り下げました。数値自体はBigInteger構造体のuint [] _data内に格納されているようです。
ヴァレラコルパエフ

*より詳細な回答で更新されましたが、逆コンパイルされたスニペットを除き、参照できる.netソースコードが見つかりません。
ヴァレラコルパエフ

:それはILSpyから把握することができるよう.NETでスタンダールの乗算アルゴリズムがあるように私には思える.NET BigIntegerの乗算
イワンKochurkin

1

制限はメモリサイズ(および使用できる時間)です。だから、あなたは本当に大きな数字を持つことができます。Kevinが言ったように、暗号では、数千(2進数)桁の数字を乗算または累乗する必要があり、これは問題なく可能です。

もちろん、数値が大きくなるとアルゴリズムは遅くなりますが、それほど遅くはありません。

ただし、メガ桁の範囲の数値を使用している場合は、他のソリューションを検討することをお勧めします。実際には、それらを使用した計算も遅くなるためです。


0

科学界ではいくつかの用途があります(つまり、銀河間の距離、草のフィールド内の原子の数など)。


失礼なことではありません..しかし、この答えは質問にどのように関連していますか?
-Pacerier

2
質問は、書かれているように、なぜそのようなデータ型を作成する必要があるのか​​という現実世界の例を探しているように聞こえます。
デイブ・ワイズ

より良い言い回しは、「BigIntegerは10 ^ 30ほどの数に本当に適していますか?」
Pacerier

このために私はより良い使用するdoubleか、floatあなたがとにかく必要な精度を持っていません- 。
パエロエベルマン

より良い言い回しは、「精度が必要なとき、BigIntegerは10 ^ 30の大きさの数値に本当に適しているのでしょうか?」
-Pacerier

0

kevin clineの答えが示唆するように、BigNumberは多くの最新の暗号化アルゴリズム(デジタル署名、公開/秘密キー暗号化など)のビルディングブロックとして必要だったため、主に.NETライブラリに追加されました。最新の暗号化アルゴリズムの多くは、最大数千ビットのサイズの整数値の計算を伴います。BigNumberクラスは適切に定義された有用なクラスを記述するため、(暗号化APIの内部詳細として保持するのではなく)公開することにしました。


ところで、BigNumbersが.NETライブラリに追加されたソースはどこにあるのでしょうか?主に、それらは多くの最新の暗号化アルゴリズムのビルディングブロックとして必要だったためです(したがって、数千ビットまでの値をサポートできるはずです)?
Pacerier
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.