私は以前BigDecimalsを使用しましたが、あまり頻繁ではなく、今朝何かに取り組んでいて、次の例外が発生し続けました。
Exception in thread "main" Java.lang.ArithmeticException: Non-terminating decimal expansion;
no exact representable decimal result.
at Java.math.BigDecimal.divide(BigDecimal.Java:1594)
私はスケールを設定し、丸めを使用して問題を排除しようとしました:
BigDecimal bd1 = new BigDecimal(1131).setScale(2,BigDecimal.ROUND_HALF_UP);
BigDecimal bd2 = new BigDecimal(365).setScale(2,BigDecimal.ROUND_HALF_UP);
BigDecimal bd3 = bd1.divide(bd2).setScale(2,BigDecimal.ROUND_HALF_UP);
System.out.println("result: " + bd3);
ただし、同じ例外が引き続き発生します。間違いを犯した場所を教えてくれる人はいますか?
divide
を使用する場合、正確な結果に無限の小数が含まれる場合(これはあなたの場合です)に、MathContext
を使用する必要があります。
MathContext mc = new MathContext(2, RoundingMode.HALF_UP);
BigDecimal bd3 = bd1.divide(bd2, mc);
または、代わりに:
BigDecimal bd3 = bd1.divide(bd2, RoundingMode.HALF_UP);
ここに問題があります
_bd1.divide(bd2)
_
オーバーロードされたdivide()
メソッドの1つを使用して、丸めモード(さまざまな形式)を使用する必要があります-終了しない分数では中間結果を既に丸める必要があるため、除算後に丸めることはできません、または無限のストレージスペースが必要です。
デフォルトでは、BigDecimalは指定された除算式の正確な値を返そうとします。このため、無限小数展開のために正確な値を決定できない場合、ArithmeticExceptionがスローされます。これの基本的な例は、1を3で除算し、結果として3分の1になることです。この値は、10進表記で正確に表すことはできません。
この問題は、10進数が繰り返される操作(除算)が原因で発生します。
解決策は、除算の実行時にscaleを指定することです。次に例を示します。
BigDecimal one = new BigDecimal("1");
BigDecimal three = new BigDecimal("3");
BigDecimal oneDivThree = one.divide(three, 200, RoundingMode.HALF_UP);
分割のためにこのエラーが発生しています:
これを防ぐために、除算方法内にスケールと丸めモード(BigDecimalsの作成時に行ったように)を提供します。
here から取得。作業部門のコード例も提供されています。
BigDecimalのJavaドキュメント も参照してください。
修正するには、次のように3番目のステーメントを変更する必要があります。
BigDecimal bd1 = new BigDecimal(1131).setScale(2,BigDecimal.ROUND_HALF_UP);
BigDecimal bd2 = new BigDecimal(365).setScale(2,BigDecimal.ROUND_HALF_UP);
BigDecimal bd3 = bd1.divide(bd2, 2, BigDecimal.ROUND_HALF_UP);
System.out.println("result: " + bd3);