为什么以下数字总和不等于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,因为它将它向上舍入。如果我明确地说,向下舍入,那么这种情况就会失败。
有关如何解决这个问题的任何建议吗?
答案 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)
也许直接检查字符串输入对你来说更可行。这是检查小数位后的字符长度。