Java中的BigDecimal

7
我考虑使用BigDecimal来比较两个货币值,这些值应该保留2位小数。例如,我期望以下比较结果为0,因为我正在比较应该四舍五入为0.02的值和实际为0.02的值。但是它返回的是-1!! 有没有正确的方法做到这一点?
这种方法也适用于更大的数字,如123.45与123.4534之间的比较...应该在使用"compareTo"函数时返回0。
我已经尝试了使用MathContext,但似乎不太优雅...是否有更好的方式?
BigDecimal spread = new BigDecimal(0.01934);
spread.setScale(2, RoundingMode.HALF_EVEN);
System.out.format("0.0193 ? 0.02 = %d\n", spread.compareTo(new BigDecimal(0.02)));

解决方案如下:

BigDecimal spread = new BigDecimal(0.01934).setScale(2, RoundingMode.HALF_EVEN);
BigDecimal loSpread = new BigDecimal(0.02).setScale(2, RoundingMode.HALF_EVEN);
System.out.format("0.0193 ? 0.02 = %d\n", spread.compareTo(loSpread));
2个回答

10

首先,BigDecimal是不可变的。你必须返回你的setScale方法调用的结果:

spread = spread.setScale(2, RoundingMode.HALF_EVEN);

接下来,您需要提高第二个BigDecimal的精度,因为它是从double中推导出来的--而double并不是一个非常准确的实体。所以请尝试使用字符串:

 spread.compareTo(new BigDecimal("0.02"))

这实际上是用来比较价格的。它们可能需要从双精度实例化。 - fodon
@fodon:那么用户unknown已经为您提供了部分答案,而我则提供了另一部分(关于BigDecimal是不可变的)。 - Hovercraft Full Of Eels
1
我撤销了无效的编辑。各位,请在您不满意已有答案时“评论”或提供“额外的答案”。 - class stacker

5

0.02会被计算为

java.math.BigDecimal = 0.0200000000000000004163336342344337026588618755340576171875

在那里你需要设置setScale(2, RoundingMode.HALF_EVEN)。


这是获取准确浮点数的另一种方式。1+。 - Hovercraft Full Of Eels
这里必须同时使用这两个想法才能做对。将发布正确的代码。 - fodon

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接