BigIntegerの乗算は、非常に大きな基数、たとえば基数2 ^ 32の標準的なロング乗算として作成できます。 それはかなり簡単です。 nを法とする結果のみが必要な場合は、 nの因数であるか、 nが因数である基数を選択すると便利です。 そうすれば、計算を実行するときに1つまたは少数の最下位の結果(Big)桁以外のすべてを無視して、スペースを節約し、時間を節約することができます。, もちろん、あなたがnを事前に知っているなら、それは最も実用的ですが、そのような予備知識は不可欠ではありません。 nが2のべき乗である場合は特に便利です。nが2のべき乗でも、システムの算術演算装置で直接処理される最大オペランドよりも小さい場合は、かなり面倒ですが、これらの場合はすべて原則として処理できます。, ただし、Java BigIntegerインスタンスで特にこれを実行する必要がある場合は、BigIntegerクラス自体では提供されていない方法で内部表現と外部表現の間の変換にオーバーヘッドが発生することに注意してください。, nを法とする 2つのBigInteger(たとえばaとb )の乗算を計算できます。, ただし、 aとbがnの次数と同じであると仮定すると、計算中に新しいBigIntegerが計算され、その長さ(バイト単位)は約2nになります。, 私が使用できるより効率的な実装があるのだろうか。 modMultiplyのようなものがmodPowのように実装されています(これは電力を計算してからモジュロを計算するのではないと考えています)。, まず、悪い知らせですが、この機能を提供する既存のJavaライブラリが見つかりませんでした。, java.math.BigInteger以外に、純粋なJavaのbig integerライブラリを見つけることができませんでした。, GMPライブラリにはJava / JNIラッパーがありますが、GMPもこれを実装していません。, 他のネイティブ(C / C ++)ビッグ整数ライブラリがこの操作をサポートするかもしれません...あなた自身のJNIラッパーを書く必要があるかもしれませんが。, java.math.BigIntegerのソースコードをコピーして追加のカスタムメソッドを追加することで、このようなメソッドを自分で実装できるはずです。 あるいは、それをextendできるように見えます。, とは言っても、Javaや他の言語でa * b mod nを計算a * b mod nための「かなり高速な」アルゴリズムがあるかどうかはわかりません。 (特別な場合は別として、例えばnが2のべき乗であるとき)。, 具体的には、 "Montgomery Reduction"アプローチは、単一の乗算ステップには役立ちません。 (ウィキペディアのページには、 「数値はモンゴメリーステップを実行するのに適した特定の形式との間で変換する必要があるため、モンゴメリーステップを使用して実行される単一の剰余乗算は、実際の「単純」よりも効率がわずかに劣ります。」, そのため、計算をスピードアップするための最も効果的な方法は、GMPにJNIラッパーを使用することです。, 次のような一般的な数学を使用できます。(A * B)mod N =((A mod N)*(B mod N))mod N, それはもっとCPUを集中的に使うかもしれませんが、CPUとメモリのどちらかを選ぶべきですね。, もし私たちがモジュラ演算について話しているなら、実際にはモンゴメリの削減があなたが必要とするものかもしれません。 ただし、すぐに使える解決策はわかりません。, BigIntegerにはtoByteArray()がありtoByteArray()が、内部的にはintが使用されます。 したがって、効果を得るためにはnはかなり大きくなければなりません。 たぶんキー生成暗号化コードでそのような仕事があるかもしれません。, そのコードは食欲をそそるようには見えません。 BigIntegerには、内部値をビッグエンディアンのbyte[]としてのみ公開するという問題があります。最初のバイトが最上位バイトです。, これは想像できないことではありません。Nが2のべき乗である場合、いくつかの良い最適化が実行可能です。, (ところで、コードはテストされていません - 納得のいくほど高速には見えません。). BigDecimalを使って4.1 * 93.03を計算 :381.423 BigDecimalを使わずに4.1 * 93.03を計算:381.42299999999994. こんにちは!エンジニアの中沢です。 Javaには誤差が出ないように正確に計算するためのBigDecimalクラスがあります。double型を使うと誤差が出て、正確に計算ができなかった経験はないでしょうか? この記事では、 BigDecimalとは BigDecimalの使い方(足し算、引き算) という基本的な内容から、 私は最近プロジェクトでSonarを使い始めました、そして私はコンストラクタnew BigDecimal(double val)を使うことに関して壊れたPMD規則を得ました。 私はjavaのドキュメントを読んだとき、私は新しいBigDecimal(double val)はやや予測不可能であり、私は予測可能なnew BigDecimal(String val)を使うべきであることを知りました。, これがjavadocがBigDecimal public BigDecimal(double val)について言うものです。, doubleを、doubleの2進浮動小数点値の正確な10進表現であるBigDecimalに変換します。 返されるBigDecimalの位取りは、(10scale×val)が整数になるような最小値です。, このコンストラクタの結果はやや予測不能になる可能性があります。 Javaでnew BigDecimal(0.1)を記述すると、 BigDecimalが正確に0.1(スケールなしの値1、スケール1)になりますが、実際には0.1000000000000000055511151231257827021181583404541015625に等しいと思われる場合があります。 これは、0.1を正確に倍精度(または、その点では、任意の有限長の2進小数)として表現できないためです。 したがって、コンストラクターに渡されている値は、外観にもかかわらず、0.1と正確には等しくありません。, 一方、Stringコンストラクターは完全に予測可能です。 new BigDecimal("0.1")を書き込むと、予想どおりに0.1に等しいBigDecimalが作成されます。 したがって、一般的にはStringコンストラクタをこれより優先して使用することをお勧めします。, doubleをBigDecimalソースとして使用する必要がある場合は、このコンストラクターが正確な変換を提供することに注意してください。 Double.toString(double)メソッドを使用してからBigDecimal(String)コンストラクターを使用してdoubleをStringに変換するのと同じ結果は得られません。 その結果を得るには、静的valueOf(double)メソッドを使用してください。, このコンストラクタが本当に存在するのはなぜですか? その問題に十分なnew BigDecimal(String val)ありませんか。 new BigDecimal(double val)コンストラクタはいつ使用すべきですか?, 実際に表現されたdouble値をBigDecimalに変換します。 BigDecimalの最大のポイントは、可能な限り高い精度を与えることであり、それがこのコンストラクタの動作です。, Double.toString(double)使用して少量の四捨五入で取得する値を取得する場合は、次のようにします。, 新しいBigDecimal(double val)コンストラクタをいつ使用するべきか, 値double本当に表す値を知りたい場合 必要に応じて独自の丸めを適用することができます。, doubleを使うときは、常に賢明な丸めを適用するべきです。 しかし、あなたがそうしたのなら、BigDecimalは必要ないと思うかもしれません。 ;).