奇怪的Java输出——使用Eclipse在Mac lion上运行VM

奇怪的Java输出——使用Eclipse在Mac lion上运行VM,java,floating-point,ieee-754,Java,Floating Point,Ieee 754,有人知道我的输出问题在哪里吗 我已经编写了一个Java程序,并用Eclipse在MacLion上的VM上运行它。 我没有得到1.41,而是在我的机器上得到了1.4100000000000001 Example: Enter the number of quarter: 4 Enter the number of dimes: 3 Enter the number of nickels: 2 Enter the number of pennies: 1 Total $1.410000000000

有人知道我的输出问题在哪里吗

我已经编写了一个Java程序,并用Eclipse在MacLion上的VM上运行它。 我没有得到
1.41
,而是在我的机器上得到了
1.4100000000000001

Example:
Enter the number of quarter: 4
Enter the number of dimes: 3
Enter the number of nickels: 2
Enter the number of pennies: 1

Total $1.4100000000000001

Example: 
Enter the number of quarter: 3
Enter the number of dimes: 2
Enter the number of nickels: 1
Enter the number of pennies: 6

Total $1.06

Example:
Enter the number of quarter: 5
Enter the number of dimes: 7
Enter the number of nickels: 4
Enter the number of pennies: 4

Total $2.1900000000000004
有时输出是正确的,但有时有问题

代码:


您的问题与浮点运算(放轻松,
float
/
double
相关计算)的发生方式有关。浮点数是一种近似的再现(如果你对背后的理论感兴趣,标准是)。这里你得到的正是,一个近似的表示


由于您处理的是仅为美分的货币(您不能有0.0001美元的货币),因此我建议使用
int
(或
long
,或任何整数类型)值表示为美分。然后,在显示结果时除以100。

您已经体验到将浮点数表示为双精度的不精确性。数字0.1不能用二进制精确表示,因此当您在Java中说
0.1
时,您可以得到与
0.1
最接近的近似值。同样的情况也适用于
0.05
0.01

您可以做以下几件事:

  • 尽可能长时间推迟浮点运算
例如:

total = quarters * 25 + dimes * 10 + nickles * 5 + pennies;
total /= 100.0;
DecimalFormat df = new DecimalFormat("0.00");
System.out.println("Total $" + df.format(total));
  • 使用a在两位小数后切断显示
例如:

total = quarters * 25 + dimes * 10 + nickles * 5 + pennies;
total /= 100.0;
DecimalFormat df = new DecimalFormat("0.00");
System.out.println("Total $" + df.format(total));

这两种解决方法都不能回避基本问题,即用
双精度
表示数字的不精确性。特别是对于金额较大的货币,不要使用
double
。你甚至可以用一个,它的精度是任意的。

我同意你为什么会遇到这个问题的解释。对于Java中的这种情况,我推荐的解决方案是使用BigDecimal。它能精确地计算出小数点后的小数。对于不精确的计算,它提供了一个很好的舍入方法选择


实际上,它使用比例因子进行整数运算,但会自动存储和管理比例。

如果使用浮点数,则需要对结果进行四舍五入。尝试
System.out.printf(“$%.2f%n”,值)我的一些证券价格以0.0001美元单位报价。程序员应该注意假设。OP处理的是真实货币(季度、一角硬币等)。没有这样的0.0001美元硬币。程序员应该注意假设。非常感谢您的所有输入。我很感激。