BigDecimalsとRoundingModeを使用して、特定の小数点以下に切り捨てられた2つのdouble型変数を比較しようとしています。
たとえば、3.1456と3.145を比較する場合、ifステートメントで小数点以下3桁に切り捨てられますが、両方の値が互いに等しい場合にのみ、私のifステートメントはtrueを返します。
しかし、それは私のコードでは機能しませんでした
BigDecimal one = new BigDecimal(3.1456).setScale(3, RoundingMode.DOWN);
BigDecimal two = new BigDecimal(3.145).setScale(3, RoundingMode.DOWN);
if (one.equals(two)) {
System.out.println("Both variables are equal");
} else {
System.out.println("Both variables are not equal");
}
出力ロジックは偽でした。そこで、変数が切り捨てられる値を確認するためにいくつかのチェックを行いました。それはそれぞれ3.145と3.144で、予想外のものでした。3.144である理由がわかりません...
次に、DecimalFormatとRoundingModeを使用して、別の方法で上記を実行しました。それはかなりうまくいきました。
DecimalFormat df0 = new DecimalFormat("#.###");
DecimalFormat df1 = new DecimalFormat("#.###");
df0.setRoundingMode(RoundingMode.DOWN);
df1.setRoundingMode(RoundingMode.DOWN);
if (df0.format(num0).equals(df1.format(num1))) {
System.out.println("Both variables are equal")
} else {
System.out.println("Both variables are not equal")
}
上記の方法は非常にうまく機能します!BigDecimalは両方の値を3.145に評価します。
DecimalFormatを使用する場合と比較して、BigDecimalを使用してタスクを実行すると機能しない理由を理解できません。double型の変数がどのように機能するかと関係がありますか?(double)(0.2-0.1)のようなもので、0.1ではなく0.09999999 ...の結果が得られますか?
より良い解決策と理解で私を啓発してください!どうもありがとうございます!
文書化されているように、これBigDecimal(double)
は予測不可能です。
このコンストラクターの結果は、いくらか予測できない場合があります。Javaで新しいBigDecimal(0.1)を書き込むと、正確に0.1(スケールが1のスケールなしの値1)に等しいBigDecimalが作成されるが、実際には0.1000000000000000055511151231257827021181583404541015625に等しいと想定する人もいるかもしれません。これは、0.1をdoubleとして正確に表すことができないためです(つまり、有限の長さの2進数の小数として)。したがって、外観にかかわらず、コンストラクターに渡される値は正確に0.1ではありません。
彼らはBigDecimal(String)
代替として使用することを提案しています
一方、文字列コンストラクターは完全に予測可能です。新しいBigDecimal( "0.1")を書き込むと、予想どおり、0.1に完全に等しいBigDecimalが作成されます。したがって、これよりもStringコンストラクターを使用することをお勧めします。
のドキュメントからBigDecimal(String)
:
BigDecimal(double)コンストラクターの予測不能性の影響を受けないため、これは一般に、floatまたはdoubleをBigDecimalに変換するための推奨される方法です。
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加