私は最近プロジェクトで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は必要ないと思うかもしれません。 ;). 桁数 - java bigdecimal 計算 順序 Javaにおける効率的なBigInteger乗算法 (4) BigIntegerの乗算は、非常に大きな基数、たとえば基数2 ^ 32の標準的なロング乗算として作成できます。 Javaには数値を扱う型として「float」や「double」などもありますが、小数点以下の正確な値の計算を行うためには「BigDecimal」を利用する必要があります。 本記事では、JavaにおけるBigDecimalの基本的な使い方をご紹介していきたいと思います。 JavaのBigDecimalとは BigDecimalを使って4.1 * 93.03を計算 :381.423 BigDecimalを使わずに4.1 * 93.03を計算:381.42299999999994. 絶対値 - java bigdecimal 計算 順序 BigDecimal(double)コンストラクタの予測不可能性 (4) 私は最近プロジェクトでSonarを使い始めました、そして私はコンストラクタ new BigDecimal(double val) を使うことに関して壊れたPMD規則を得ました。 こんにちは!エンジニアの中沢です。 Javaには誤差が出ないように正確に計算するためのBigDecimalクラスがあります。double型を使うと誤差が出て、正確に計算ができなかった経験はないでしょうか? この記事では、 BigDecimalとは BigDecimalの使い方(足し算、引き算) という基本的な内容から、 javaで浮動小数を計算する場合、BigDecimalクラスを利用しましょう。float型やdouble 型では誤差が出る可能性があります!実務の中で厳密なお金の計算をする場合、特に外貨などを扱う必要が場合は、BigDecimal クラスは必須です。使い方をサンプルを用いて説明します。 ュテーブルの鍵などとして使用することができることを意味します。ロケールに依存する数値のフォーマットと解析は、, 技術表記法での指数を使用した数値表現には. Java、BigDecimal。 分割の問題 (3) 割合の「係数」を計算しようとしています。 つまり、20%が与えられたら、それを0.2に変換します(私の意図は、後でそれに値を掛けて値の20%を取得することです)。 あなたがBigDecimalsで遊んでも構わないと思っているのであれば、doubleでコンストラクタを使うことは正確な​​数の表示のすべての利点を失うことを意味します。, 時々あなたは二倍しか持っていないので、あなたはBigDecimalに翻訳したいのです。 その間に.toString()を使わざるを得なくなるのは、ばかげているでしょう;), もしあなたが本当に "0.1"を意味していたら、はい、Stringコンストラクタを使用してください=)しかし、もしあなたがすでにdoubleを持っているなら、そのdoubleは "0.1"ではありません。, doubleをBigDecimalのソースとして使用する必要がある場合は、このコンストラクターが正確な変換を提供することに注意してください。, 正確な変換がどのように「予測不可能」であるかはわかりません。この引用から「絶対必要」という言葉を削除することに賛成です。, 結局のところ、両方のコンストラクタは意図したとおりに動作します。 文字列 "0.1"がある場合、BigDecimal(String)はこの値を正確に変換します。 doubleの0.1がある場合、BigDecimal(double)はこの値を正確に変換します。, 処理したいデータがすでにdouble値として存在する場合は、doubleコンストラクターを使用します。 その場合、BigDecimalに変換する前にそれを文字列に変換する必要があるのは無駄です。, 0.1000000000000000055511151231257827021181583404541015625. BigDecimal の自然順序 ... Java で new BigDecimal(0.1) ... コンテキスト設定に従った丸めを使用して計算された divideToIntegralValue の結果と、2 つのオペランドの remainder の結果を含む、2 要素の BigDecimal 配列を返します。

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を使うことで、小数点以下を正確に計算できていることがわかります。 入門向けJavaの学習サイトもまとめているので、合わせてご覧ください。 When should I use the new BigDecimal(double val) constructor? 比較 - java bigdecimal 計算順序 . public、protected、package-private、privateのJavaの違いは何ですか.