double 値の小数点以下 2 桁を保持する方法をいくつか見つけようとしています。現在、以下の5つの方法を試しました。
- java.math.BigDecimal を使用
- java.text.DecimalFormat を使用
- java.text.NumberFormat を使用する
- java.util.Formatter を使用する
- String.format を使用
これら 5 つの方法の結果は、基本的に一貫しています。ただし、一部のシナリオでは、java.math.BigDecimal は他の 4 つのメソッドとは異なる結果になります。
たとえば、double 値100.0050Dを使用します。
java.math.BigDecimal を使用すると、私のコードでは 100.00 が返されます。ただし、他の 4 つのメソッドは 100.01 を返します。結果は矛盾しています。
実際には、RoundingMode.HALF_UPが使用されます。ここに私の質問があります:
以下のコードで、java.math.BigDecimal を使用して double 値で小数点以下 2 桁を保持するために見逃したものはありますか?
それとも、クラス java.math.BigDecimal の小さな欠陥ですか?
これで私を助けてください。前もって感謝します。
さらに、さまざまなJDKバージョンで異なるかどうかはわかりません。使用したJDKのバージョンが1.7.0_25であるという情報を提供するだけです。
コードは次のとおりです。
public final class PrecisionTest {
private PrecisionTest() {
}
public static String format1(double value) {
BigDecimal bd = new BigDecimal(value);
bd = bd.setScale(2, RoundingMode.HALF_UP);
return bd.toString();
}
public static String format2(double value) {
DecimalFormat df = new DecimalFormat("0.00");
df.setRoundingMode(RoundingMode.HALF_UP);
return df.format(value);
}
public static String format3(double value) {
NumberFormat nf = NumberFormat.getNumberInstance();
nf.setMaximumFractionDigits(2);
nf.setMinimumFractionDigits(2);
nf.setRoundingMode(RoundingMode.HALF_UP);
nf.setGroupingUsed(false);
return nf.format(value);
}
public static String format4(double value) {
return new Formatter().format("%.2f", value).toString();
}
public static String format5(double value) {
return String.format("%.2f", value).toString();
}
}
簡単なテスト コードは次のとおりです。
public class Main {
public static void main(String[] args) {
double[] testData = new double[] { 100.123D, 1234567.897D, 100.0050D,
80.0051D,-100245.3658D};
for (double value : testData) {
System.out.println(PrecisionTest.format1(value));
System.out.println(PrecisionTest.format2(value));
System.out.println(PrecisionTest.format3(value));
System.out.println(PrecisionTest.format4(value));
System.out.println(PrecisionTest.format5(value));
}
}
}