【问题标题】:Java BigDecimal operations "arbitrarily" showing incorrect number of decimal placesJava BigDecimal 操作“任意”显示不正确的小数位数
【发布时间】:2020-05-13 17:55:28
【问题描述】:

我正在尝试使用 BigDecimal 类解决一个练习,但对于某些值,它不尊重要显示的正确小数位数。 对于 5.0 到 12.5 的值,它显示额外的小数位。知道为什么吗?提前致谢。

这是代码的改编版本:

MathContext mc = new MathContext(2, RoundingMode.UP);

BigDecimal min = new BigDecimal("2.00");
BigDecimal adt = new BigDecimal("0.50");
BigDecimal lim = new BigDecimal("3.00");

for (float f = 5f; f <= 30f ; f += 0.5f) {
    String s = Float.toString(f);
    BigDecimal hours = new BigDecimal(s);
    BigDecimal charge = min.add(hours.subtract(lim).round(mc).multiply(adt));
    System.out.println(f + " = " + charge);
}

输出:

5.0 = 3.000
5.5 = 3.250
6.0 = 3.500
6.5 = 3.750
7.0 = 4.000
7.5 = 4.250
8.0 = 4.500
8.5 = 4.750
9.0 = 5.000
9.5 = 5.250
10.0 = 5.500
10.5 = 5.750
11.0 = 6.000
11.5 = 6.250
12.0 = 6.500
12.5 = 6.750
13.0 = 7.00
13.5 = 7.50
14.0 = 7.50
14.5 = 8.00
15.0 = 8.00
15.5 = 8.50
16.0 = 8.50
16.5 = 9.00
17.0 = 9.00
17.5 = 9.50
18.0 = 9.50
18.5 = 10.00
19.0 = 10.00
19.5 = 10.50
20.0 = 10.50
20.5 = 11.00
21.0 = 11.00
21.5 = 11.50
22.0 = 11.50
22.5 = 12.00
23.0 = 12.00
23.5 = 12.50
24.0 = 12.50
24.5 = 13.00
25.0 = 13.00
25.5 = 13.50
26.0 = 13.50
26.5 = 14.00
27.0 = 14.00
27.5 = 14.50
28.0 = 14.50
28.5 = 15.00
29.0 = 15.00
29.5 = 15.50
30.0 = 15.50

【问题讨论】:

  • 你永远不应该使用浮点类型作为 for 循环的索引。
  • 您可以使用 MathContext 对象进行舍入,但仅用于显示。
  • @DavidConrad:尽管在这种情况下它可以工作,这既是因为&lt;=,也是因为所有的值都可以精确地表示。
  • @PresidentJamesK.Polk 是的,但是养成循环花车的习惯会让自己为未来的心痛做好准备,我相信你知道。

标签: java formatting decimal bigdecimal


【解决方案1】:

问题可能是对MathContext的误解。对于MathContext(2, RoundingMode.UP),您不是说“我想要 2 位小数”,而是说“我想将我的数字的精度降低到 2 位”。

如果您查看您的数字,小数位数(小数位数)为 2,其中 hours - lim &gt;= 10

如果你仔细看看hours=12.5hours=13.0这两个例子

//hours = 12.5:
var subtract = hours.subtract("3.00"); // 12.5 - 3.00 = 9.50 (subtract.scale = 2)
var round = subtract.round(mc); // 9.5 (round.scale = 1)
var result = round.multiply("0.50") // 9.5 * 0.50 = 4.750 (result.scale = round.scale + subtract.scale = 3)
//hours = 13.0:
var subtract = hours.subtract("3.00"); // 13.0 - 3.00 = 10.00 (subtract.scale = 2)
var round = subtract.round(mc); // 10 (round.scale = 0)
var result = round.multiply("0.50") // 10 * 0.50 = 5.00 (result.scale = round.scale + subtract.scale = 2)

您会看到四舍五入的小数位数在其值变为 >= 10 时立即变为 0。乘法结果的小数位数始终是两个乘数的小数位数之和。

要设置BigDecimal 的比例,请使用BigDecimal.setScale(int, RoundingMode) 而不是MathContext

【讨论】:

  • 尝试使用 .setScale,效果很好,谢谢。这整个规模的事情非常令人困惑
猜你喜欢
  • 2021-09-20
  • 2021-04-07
  • 1970-01-01
  • 2017-07-26
  • 2014-07-17
  • 1970-01-01
  • 2016-07-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多