Javaで倍精度の問題と解決策をBigDecimal

Javaで倍精度の問題と解決策をBigDecimal

 

最近、古いJ2EEコードの自由なポイントを書いて、非常に興味深い質問を見つけたフロートに休止状態を使用している場合、そのような要約の蓄積としていくつかの作業を、行うために、データベースから読み出したかのように降順あなたは、最終的な結果には少し問題があることがわかります。
以下のような:3.41 + 5.2 + 56.2 + 23.3 + ...(この二つの小数位の価格)、結果は103.00000000000001この結果に表示されますが、人々は数える、それは通常のデータに来ます。それは、二重表示され、そのようなデータの精度アップフロートは、このような問題が発生します。
    次に、Javaのこの状況に対処するために、任意のプログラミング言語で通貨の特殊なタイプを提供するために、データポイントをオンにではなく。
    丸みを帯びた
私たちの最初の反応は、丸め行うことです。メソッドの予約ラウンドMathクラスは、我々だけで、いくつかの小数点以下の桁数を設定することはできません
。この(2予約)のような:
公共ダブルラウンド(ダブル値){
    リターン恐らくMath.round(値* 100)/100.0;
}
残念ながら、上記そしてコードは仕事、この方法を与えるには、入ってくる4.015 4.01の代わりに4.02を返しますしない
、我々は上記参照として
4.015 * 100 = 401.49999999999994
私たちは、正確な丸めを達成する必要がある場合は、シンプルな操作のいずれかのタイプを行うことはできませんので
Javaの.text.DecimalFormatは、この問題を解決することはできません:
System.out.printlnは、(新新java.text.DecimalFormatの( "0.00")フォーマット(4.025)。)
出力は4.02であります

BigDecimalの
「効果的なJavaの」この本はまた、この原理を述べ、floatとdouble缶のみ科学技術計算やのために使用することで
、コンピューティング技術、ビジネスコンピューティングは、我々はjava.math.BigDecimalのを使用しています。パーティー作る4の合計を記入しBigDecimalの
法律を、私たちはこれら二つのBigIntegerを利用するには十分気にしない、2つがあり、それらは:
BigDecimalを(ダブルヴァル)
          変換するAダブルINTO AのBigDecimal。
BigDecimalを(文字列ヴァル)
          翻訳BigDecimalのINTOでrepre- sentationの文字列
をBigDecimal。
簡単にAPI、上記のは非常に明確であり、通常、上記の1は、使用に便利なように。私は
、問題が何であるか、それはそれについて考えるかもしれません使用する必要がありますか?それが十分になさ上記の当事者ことがわかっ問題まで待つ
:メソッドの詳細な説明は、これは言っている
一つは、可能性があります予想外である可能性がで、このコンストラクタの注:。結果
新しい新しいのBigDecimal(0.1)が完全に等しいとされていると仮定します。 1、実際には同じです
のでへ。この.1000000000000000055511151231257827021181583404541015625はSO IS
0.1が正確に(その問題、AS Aバイナリためか、AS Aダブル表現されていないことができます
任意の有限の長さの割合を)。このように、値はISに渡されていることをロング
ザ・は正確にコンストラクタではありません。0.1同等に出演がnonwithstanding、である
(String)コンストラクタで、手他方にONは、完全に予測可能である:新新
(「1」)のBigDecimalを正確に等しい0.1、ASの一つだろうにあるそのため期待し、それは。
一般的にすることを推奨(String)コンストラクタでに優先して使用する
。この一つ。

私たちは、正確な計算ならば必要があるとしていない十分なのBigDecimalに文字列を作るために!「効果的なJavaの」で
書籍の一例をBigDecimalに文字列を作成するには十分であるが、本はこの点を強調していなかった、これがかもしれ
小さなミスも。

ソリューション
今、私たちはこの問題を解決する必要があり、原則はBigDecimalのを使用することで、ビルドに文字列に十分なを使用する必要があります。
しかし、その後、十分に作成し、我々は加算演算を行う場合、あなたは文字列への最初の2つの浮動小数点数に必要な、それを想像する
操作の結果、その後、パラメータとして別のものを渡して、呼び出しが上に追加している、BigDecimalをします(
BigDecimalの)とは、その後、浮動小数点数に変換します。あなたは、このような面倒なプロセスを置くことができますか?下に私たちは、ツールクラスを提供
流線操作にARITHを。:それは、加算、減算および丸めを含む次の静的メソッド、提供
の追加(ダブルV1、V2ダブル)パブリック静的ダブルを
パブリック静的ダブルサブ(ダブルV1、V2ダブル)
パブリック静的ダブルMUL(ダブルV1、V2ダブル)
パブリック静的ダブルのdiv (ダブルV1、V2ダブル)
パブリック静的ダブルDIV(ダブルV1、V2ダブル、int型のスケール)
パブリック静的ダブルラウンド(ダブルV、int型のスケール)

付録

ソースファイルArith.java:
com.common.utilのためのパッケージ変更;
java.mathのインポートクラス.BigDecimal;

publicクラスARITH最終{
//デフォルトの分割精度
プライベート静的最終int型のDEF_DIV_SCALE = 2;
//这个类不能实例化
プライベートARITH(){
}

パブリック静的ダブル追加(二重V1、V2ダブル){
  BigDecimalをB1 =新規のBigDecimal(持つDouble.toString(V1))。
  BigDecimalのB2 =新しいBigDecimalを(持つDouble.toString(V2));
  .doubleValueを()b1.add(b2)を返します。
}

パブリック静的ダブルサブ(ダブルV1、V2ダブル){
  BigDecimalをB1 =新規のBigDecimal(持つDouble.toString(V1))。
  BigDecimalのB2 =新しいBigDecimalを(持つDouble.toString(V2));
  リターンb1.subtract(B2).doubleValue();
}

パブリック静的ダブルMUL(ダブルV1、V2ダブル){
  BigDecimalをB1 =新規のBigDecimal(持つDouble.toString(V1))。
  BigDecimalのB2 =新しいBigDecimalを(持つDouble.toString(V2));
  b1.multiply返す(B2).doubleValue();
}

パブリック静的ダブルDIV(ダブルV1、V2ダブル){
  戻りDIV(V1、V2、DEF_DIV_SCALE)。
}

パブリック静的ダブルDIV(ダブルV1、V2ダブル、INTスケール){
  IF(スケール<0){
   新をスロー(
   「スケールは正の整数またはゼロでなければなりません」)。
  }
  のBigDecimal B1 =新規のBigDecimal(持つDouble.toString(V1))。
  BigDecimalのB2 =新しいBigDecimalを(持つDouble.toString(V2));
  戻りb1.divide(B2、スケール、BigDecimal.ROUND_HALF_UP).doubleValue();
}

パブリック静的ダブルラウンド(ダブルV、INTスケール){

公開された900元の記事 ウォンの賞賛387 ビュー279万+

おすすめ

転載: blog.csdn.net/kingmax54212008/article/details/104016809