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

标签 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);

我预计它会将 itemDiscount 的值设置为 15,但令人惊讶的是它有 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。

如果出现这种情况,该如何解释?这是事实还是错误?

最佳答案

What is the explanation if this case? is this the way it is or it is a bug?

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

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

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

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

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

关于java - Java 中奇怪的十进制计算,可能是一个错误?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18305673/

相关文章:

python - 如何在 python 3 中获取小数列表

c# - 在 .NET 中除两位小数时出现溢出异常

java - href 链接的 XPATH 不起作用。获取无效选择器 : It should be an element

algorithm - 比较两个点数组

php - 如何评估在 PHP 中作为字符串传递的公式?

javascript - Javascript Math.max 和 Math.min 实际上是如何工作的?

c++ - 如何在保持显示位数的同时向左移动小数点?

java - 查询多种文档类型 Spring Mongo

rake db 的 Java EE 替代品 :migrate

java - DAO 方法检索单个条目