0

我有奇怪的十进制计算,真的让我吃惊,我有两个大十进制数字,一个是正常过程,另一个是报价。然后我想计算折扣百分比并将其限制为最接近的整数。

这是代码:

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。

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

4

2 回答 2

2

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

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

于 2013-08-19T02:43:32.273 回答
2

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

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

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

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

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

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

于 2013-08-19T02:51:12.527 回答