なぜnew BigDecimal("0.015").compareTo(new BigDecimal(0.015))
は-1を返しますか? 私はそれらの2つが等しいと思ったら、それを比較する別の方法がありますか?新しいBigDecimal( "0.015")。compareTo(新しいBigDecimal(0.015))は-1を返しますか?
答えて
double
はまさに値0.015
を表現することはできません。 64ビットの2進数で表現できる最も近い値は0.01499999999999999944488848768742172978818416595458984375
です。コンストラクタnew BigDecimal(double)
は、double
引数の正確な値を保持するように設計されています。正確には0.015
になることはありません。したがって、あなたの比較の結果。しかし
、あなたがすることによって例えばdouble
値は、ことを表示した場合:
System.out.println(0.01499999999999999944488848768742172978818416595458984375);
それは0.015
を出力 - 回避策を示唆しています。 Converting a double
to a String
は、他の可能なdouble
値と区別するのに必要な最短10進表現を選択します。
あなたはdouble
のString
表現からBigDecimal
を作成する場合は、期待どおりこのように、それはより多くの価値を持つことになります。実際に
new BigDecimal(Double.toString(0.015)).equals(new BigDecimal("0.015"))
あなたがに上記を短縮することができますので、この方法BigDecimal.valueOf(double)
は、まさにこの目的のために存在します:本当です。この比較
BigDecimal.valueOf(0.015).equals(new BigDecimal("0.015"))
あなたは、あなたの目的がある場合にのみ、new BigDecimal(double)
コンストラクタを使用する必要があります引数の正確なバイナリ値を保持します。
これは、一般的に
double
(またはfloat
)BigDecimal
に変換するための望ましい方法です。そうでない場合は、そのドキュメント言い、BigDecimal.valueOf(double)
を呼び出します。
それともあなたがして完全にdouble
の機微を避けることができれば、String
を使用しています。
により浮動小数点演算の不正確な性質のために、彼らはBigDecimalのさまざまなコンストラクタが受け入れる、@Reimeusからanswerに展開するには、正確に等しい
System.out.println(new BigDecimal(0.015));
ディスプレイ
0.01499999999999999944488848768742172978818416595458984375
'System.out.println(新しいBigDecimal(" 0.015 "));は正確に0.015を表示します。 – gla3dr
'' '新しいBigDecimal(0.015)' 'が' '' BigDecimal( "0.015") '' 'と等しくなることを期待したら、どうすれば比較できますか? – Glide
あなたはそれらが同等であるとは限りません。浮動小数点演算を使用するたびに、これらの種類のエラーが発生することに注意する必要があります。 – vonPetrushev
じゃありません異なるタイプの入力。 浮動小数点コンストラクタは、入力として浮動小数点を取り、浮い方法の制限のために/ダブルスが格納されているため、これらは、例えば、正確に2
程度のパワーである値を格納することができます、2-2、または0.25を正確に表すことができる。 0.875は(2 -1 + 2 -2 + 2 -3)であるので、正確に表すこともできる。その数が、上限と下限の差が53以下である総和で表すことができる限り、その数は正確に表すことができます。大部分の数字はこのパターンに適合しません!
特に、0.15は2の累乗ではなく、2の累乗でもないため、表現が正確ではありません。
一方、文字列コンストラクタは、数値を格納するために内部的に異なる形式を使用して正確に格納します。したがって、あなたが2つを比較するとき、彼らは異なっているとして比較します。ここで実際に何が起こる
より正確には、「2のべき乗の整数倍」。 0.75を正確に表すことができる。 –
整数が<2^53 ... –
@PatriciaShanahan公正である限り...私は答えを更新します。 –
はこれです:
0.015
はプリミティブなdoubleです。つまり、それを書くとすぐに、それはすでに0.015でなく、むしろ0.0149...
です。 コンパイラは、それをバイトコードのバイナリ表現として格納します。BigDecimal
は正確、それに与えられているものは何でもを保存するように構成されています。この場合、0.0149...
BigDecimal
も、正確な表現に文字列を解析することができます。この場合、"0.015"
は正確には0.015
に解析されます。double
はその数を表すことができないにもかかわらず、BigDecimal
缶- は最後に、あなたがそれらを比較するとき、あなたは彼らが等しくないことがわかります。どちらが理にかなっている。
BigDecimal
を使用する場合は、以前使用したタイプに注意してください。 String
,int
,long
は正確なままです。 float
およびdouble
には、通常の精度の警告があります。
この投稿をチェックしてください:http://stackoverflow.com/questions/6058984/bigdecimal-compareto-not-working-as-expected?rq=1 – MFazio23
新しいBigDecimal( "0.015" ) '。 @ Reimeusが彼の答えで指摘した理由で。 –
あなたは、異なる計算から生まれた2つのダブルを比較するのと同じように比較を行うことができます。 –