所有double的Java总和不返回预期结果

时间:2013-01-08 14:53:10

标签: java sum double floating-accuracy decimalformat

  

可能重复:
  Moving decimal places over in a double

为什么以下数字总和不等于0.4622?但是0.46219999999999994

Double total = new Double(0.08) + new Double(0.0491) + new Double(0.3218) + 
         new Double(0.0113) + new Double(0.0); // = 0.46219999999999994

我有一个检查用户输入的应用程序。

用户输入5个十进制数和一个总数。应用程序检查komma后面4位小数的所有5个数字的总和是否等于总数。

加盖它会让我0.4621不等于0.4622。我不能使用DecimalFormat,因为它将它向上舍入。如果我明确地说,向下舍入,那么这种情况就会失败。

有关如何解决这个问题的任何建议吗?

10 个答案:

答案 0 :(得分:10)

尝试使用java.math.BigDecimal。双轮结果。您只需使用add方法,而不是+运算符。

答案 1 :(得分:4)

如果需要确切答案,请避免使用float和double-- Item 48 - Effective Java Second edition

改为使用BigDecimal

答案 2 :(得分:2)

看起来像浮点运算的经典案例。如果您想要精确计算,请使用java.math.BigDecimal。看看What Every Computer Scientist Should Know About Floating-Point Arithmetic

答案 3 :(得分:1)

这是另一个四舍五入的问题。你永远不应该比较双打,并期望它们完全相同。而是定义一个小的epsylon并期望结果在预期答案的epsylon内。

答案 4 :(得分:1)

浮点表示是一个近似值,因此当您使用float和double时,您将遇到这些小的舍入误差。例如,如果您尝试将0.08转换为二进制,您将意识到您实际上无法完全执行此操作。无论何时在计算中使用double和float,都需要考虑这一点。

0.08 10 = 0.00010100011110101110 ... 2

重复模式。因此,无论您使用多少位,都会产生舍入误差。

答案 5 :(得分:1)

使用浮点运算时,还必须使用适当的舍入。

BTW:当基元可以使用时,不要使用对象。

double total = 0.08 + 0.0491 + 0.3218 + 0.0113 + 0.0;
System.out.printf("%.4f%n", total);

double rounded = Math.round(total * 1e4) / 1e4;
if (rounded == 0.4622)
    System.out.println("rounded matched");

打印

0.4622
rounded matched

正如所料。

答案 6 :(得分:1)

Java中的Double和float在内部表示为二进制分数,因此在表示小数分数时可能不精确(IEEE标准754)。如果您的十进制数计算需要精确度,请使用Java.math.BigDecimal

答案 7 :(得分:0)

任何浮点值都不准确。当您必须显示值时,解决方案 以使用DecimalFormat。不,它不会向上舍入,而是到最接近的值。

来自javadoc:

  

DecimalFormat使用半偶数舍入(请参阅ROUND_HALF_EVEN)   格式化。

答案 8 :(得分:0)

像Double这样的浮点数的内部表示永远不是一个精确的。这就是为什么在计算过程中会出现这种错误的原因。

始终建议将此类结果格式化为逗号之后的特定位数,因此您的结果将正确显示为“0.4622”,数字为4到15或更多。

答案 9 :(得分:0)

也许直接检查字符串输入对你来说更可行。这是检查小数位后的字符长度。