Javaでは、double値を取得してBigDecimal
に変換し、その文字列値を特定の精度で出力します。
import Java.math.BigDecimal;
public class Main {
public static void main(String[] args) {
double d=-.00012;
System.out.println(d+""); //This prints -1.2E-4
double c=47.48000;
BigDecimal b = new BigDecimal(c);
System.out.println(b.toString());
//This prints 47.47999999999999687361196265555918216705322265625
}
}
この巨大なものを印刷します:
47.47999999999999687361196265555918216705322265625
ではなく
47.48
私がBigDecimal
変換を行う理由は、倍精度の値に小数点以下の桁が多く含まれる場合があり(つまり、-.000012
)、倍精度を文字列に変換すると科学表記法-1.2E-4
が生成されるためです。非科学表記法で文字列値を保存したい。
BigDecimalには、常に「47.48」のような2つの精度単位が必要です。 BigDecimalは、文字列への変換の精度を制限できますか?
別の MathContext を使用すると、47.48000が出力されます。
BigDecimal b = new BigDecimal(d, MathContext.DECIMAL64);
必要なコンテキストを選択してください。
このような動作の理由は、印刷される文字列が正確な値-おそらく期待したものではないが、メモリに保存される実際の値-浮動小数点表現の制限にすぎないためです。
Javadocによると、BigDecimal(double val)コンストラクターの動作は、この制限を考慮しないと予期しないものになる可能性があります。
このコンストラクタの結果は、いくぶん予測不能です。 Javaに新しいBigDecimal(0.1)を書き込むと、0.1(スケールなしの値1、スケール1)に完全に等しいBigDecimalが作成されますが、実際には0.1000000000000000055511151231257827021181583404541015625に等しくなります。これは、0.1をdoubleとして正確に表現できないためです(つまり、有限長の2進小数として表現することはできません)。したがって、コンストラクターに渡される値は、外観にかかわらず、0.1に正確には等しくありません。
だからあなたの場合、代わりに
double val = 77.48;
new BigDecimal(val);
つかいます
BigDecimal.valueOf(val);
BigDecimal.valueOfによって返される値は、Double.toString(double)
の呼び出しの結果と同じです。
String.format("%f", d)
を試してみてください。これは、10進表記でdoubleを出力します。 BigDecimal
を使用しないでください。
精度の問題に関して:最初に47.48
にdouble c
を保存し、次にそのBigDecimal
から新しいdouble
を作成します。精度の低下は、c
への割り当てにあります。できる
BigDecimal b = new BigDecimal("47.48")
精度が失われないようにします。
何故なの :
b = b.setScale(2, RoundingMode.HALF_UP);
double
の実際の正確な値を出力しています。
double
sをString
sに変換するDouble.toString()
は、not入力の正確な10進値を出力します-x
があなたのdouble値の場合、 x
が印刷した値に最も近いdouble
になるように正確に十分な桁を出力します。
ポイントは、そのようなdouble
はないが正確に47.48であるということです。 Doublesは、値をbinary decimalとしてではなく、分数として格納するため、正確なdecimal値を格納できません。 (それがBigDecimal
の目的です!)
String.format構文は、doubleおよびBigDecimalsを任意の精度の文字列に変換するのに役立ちます。
このJavaコード:
double dennis = 0.00000008880000d;
System.out.println(dennis);
System.out.println(String.format("%.7f", dennis));
System.out.println(String.format("%.9f", new BigDecimal(dennis)));
System.out.println(String.format("%.19f", new BigDecimal(dennis)));
プリント:
8.88E-8
0.0000001
0.000000089
0.0000000888000000000
BigDecimal b = new BigDecimal(c).setScale(2,BigDecimal.ROUND_HALF_UP);
Java 9では、以下は非推奨です。
BigDecimal.valueOf(d).
setScale(2, BigDecimal.
ROUND_HALF_UP);
代わりに使用します:
BigDecimal.valueOf(d).setScale(2, RoundingMode.HALF_UP);
例:
double d = 47.48111;
System.out.println(BigDecimal.valueOf(d)); //Prints: 47.48111
BigDecimal bigDecimal = BigDecimal.valueOf(d).setScale(2, RoundingMode.HALF_UP);
System.out.println(bigDecimal); //Prints: 47.48