Java中奇怪的十进制计算,可能是一个错误?

时间:2013-08-19 02:37:44

标签: java math decimal

我有奇怪的十进制计算让我感到惊讶,我有两个大的十进制数,一个是正常程序,另一个是报价。然后我想计算折扣百分比并将其细化到最接近的整数。

以下是代码:

BigDecimal listPrice = new BigDecimal(510000);
BigDecimal offerPrice = new BigDecimal(433500);
int itemDiscount = (int)Math.ceil(((listPrice.longValue() - offerPrice.longValue()) / (float) listPrice.longValue()) * 100);

我预计它会将15设置为itemDiscount的值,但令人惊讶的是它有16,哇。然后我打印每个计算以显示哪个语句是问题,所以我为每个语句放置System.out.println,如下所示:

System.out.println(listPrice.longValue() - offerPrice.longValue()); //==> show 76500
System.out.println((listPrice.longValue() - offerPrice.longValue()) / (float) listPrice.longValue()); // ==> 0.15
System.out.println((listPrice.longValue() - offerPrice.longValue()) * 100 / (float) listPrice.longValue()); // ==> 15.000001

问题出在上面的陈述中,而不是返回15.0,它返回15.000001。当我告知它时,它当然会返回16而不是15。

如果是这种情况有什么解释?这是它的方式还是一个错误?

2 个答案:

答案 0 :(得分:2)

直接尝试使用BigDecimal类中的divide方法。如果你要转换为浮点数,那么你没有使用BigDecimal的好处。

http://www.roseindia.net/java/java-bigdecimal/bigDecimal-divide-int.shtml

答案 1 :(得分:2)

  

如果是这种情况有什么解释?这是它的方式还是一个错误?

就是这样。这不是一个错误。

您正在使用浮点类型(float)进行计算,浮点运算不精确。

我不确定这里最好的解决办法是什么。也许使用BigDecimal算术方法进行计算可以得到更好的结果,但绝不保证在不同输入的计算中你不会遇到类似的问题......

但是,我怀疑真正的问题是你不应该在该计算中使用ceil。即使是BigDecimal也会给你舍入错误;例如如果你的计算涉及除以3,则不能使用基数10表示精确地表示中间结果。

使用实数进行计算的正确方法是正确考虑计算中的误差线。