gpt4 book ai didi

java.math.BigDecimal 并不总是适用于保留两位小数?

转载 作者:行者123 更新时间:2023-12-01 08:08:17 24 4
gpt4 key购买 nike

我正在尝试找出几种方法来为 double 值保留两位小数。目前我尝试了以下5种方法。

  • 使用 java.math.BigDecimal
  • 使用java.text.DecimalFormat
  • 使用java.text.NumberFormat
  • 使用 java.util.Formatter
  • 使用 String.format

这5种方法的结果基本一致。但在某些场景下,java.math.BigDecimal 的结果与其他 4 种方法不同。

以双值100.0050D为例:

使用 java.math.BigDecimal 时,它在我的代码中返回 100.00。然而其他 4 个方法返回 100.01。结果不一致。

实际上,使用了RoundingMode.HALF_UP。我的问题来了:

在下面的代码中使用 java.math.BigDecimal 保留 double 值的两位小数,我错过了什么吗?

还是 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));
}
}
}

最佳答案

100.005 的 double 表示并不精确,并且略小于 100.005:

scala> new java.math.BigDecimal(100.0050)
res0: java.math.BigDecimal = 100.0049999999999954525264911353588104248046875

因此,当您设置比例和舍入模式时,它会向下舍入为 100.00。

另一方面,使用 String 构造 BigDecimal 可以按预期工作:

scala> new java.math.BigDecimal("100.0050")
res2: java.math.BigDecimal = 100.0050

scala> res2.setScale(2, java.math.RoundingMode.HALF_UP).toString
res3: java.lang.String = 100.01

关于java.math.BigDecimal 并不总是适用于保留两位小数?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19616243/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com