私が欲しいのは、doubleをハーフアップ法で丸める文字列に変換する方法です。例えば、丸める小数が5の場合、常に次の数字に丸めます。これは、多くの人が期待する標準的な丸め方です。
また、有効数字のみを表示させたいと考えています。つまり、末尾にゼロがあってはならないのです。
これを実現する方法として、String.format
メソッドを使う方法があります。
String.format("%.5g%n", 0.912385);
を返します。
0.91239
を返します。これは素晴らしいことですが、重要でない数字であっても常に小数点以下5桁の数字が表示されます。
String.format("%.5g%n", 0.912300);
を返します。
0.91230
もうひとつの方法は、DecimalFormatter
を使うことです。
DecimalFormat df = new DecimalFormat("#.#####");
df.format(0.912385);
を返すことです。
0.91238
しかし、見ての通り、これは半偶数丸めを使用しています。つまり、前の桁が偶数の場合は切り捨てられます。私が望むのはこれです。
0.912385 -> 0.91239
0.912300 -> 0.9123
これをJavaで実現するには、どのような方法がありますか?
setRoundingMode][1]を使用し、[
RoundingMode`]2を明示的に設定して半偶数ラウンドの問題を処理し、必要な出力のためにフォーマットパターンを使用します。
例
DecimalFormat df = new DecimalFormat("#.####");
df.setRoundingMode(RoundingMode.CEILING);
for (Number n : Arrays.asList(12, 123.12345, 0.23, 0.1, 2341234.212431324)) {
Double d = n.doubleValue();
System.out.println(df.format(d));
}
が出力されます。
12
123.1235
0.23
0.1
2341234.2125
EDIT:元の回答では、2倍の値の精度については触れていません。丸めるか丸めないかをあまり気にしない場合はそれでいいと思います。しかし、正確な丸めをしたいのであれば、値の予想される精度を考慮する必要があります。浮動小数点値は、内部的には2進法で表現されています。つまり、2.77395のような値は、実際には内部でその正確な値を持っているわけではないということです。わずかに大きくなることもあれば、わずかに小さくなることもあります。もし、内部の値がわずかに小さければ、2.7740には丸められません。このような状況を改善するには、扱う値の精度を意識して、丸める前にその値を加減する必要があります。例えば、値が6桁まで正確であることがわかっている場合、半端な値を切り上げるには、その精度を値に加えます。
Double d = n.doubleValue() + 1e-6;
切り捨てる場合は、精度を差し引きます。