>有人知道我的输出问题在哪里吗?
我编写了一个Java程序,并使用Eclipse在Mac lion上的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
有时输出似乎是正确的,而有时则有问题。
法典:
import java.util.*;
public class CountChange
{
public static void main(String[]args)
{
Scanner inputScanner = new Scanner(System.in);
System.out.print("Enter the number of quarters: ");
int quarters = inputScanner.nextInt();
System.out.print("Enter the number of dimes: ");
int dimes = inputScanner.nextInt();
System.out.print("Enter the number of nickles: ");
int nickles = inputScanner.nextInt();
System.out.print("Enter the number of pennies: ");
int pennies = inputScanner.nextInt();
inputScanner.close();
double total =0.00;
total = quarters * 0.25 + dimes * 0.1 + nickles * 0.05 + pennies * 0.01;
System.out.println("Total $" + total);
System.out.print("Thank you");
}
}
您的问题与浮点数(简单来说,float
/double
相关计算)的发生方式有关。浮点数是一个近似的再现(如果你对背后的理论感兴趣,标准是IEEE754)。在这里,你得到的正是这个,一个近似的表示。
由于您正在处理的钱只能用美分(您不能有 0.0001$ 的货币),我建议将具有 int
(或 long
或任何整数类型)值的值表示为美分。然后,在显示结果时除以 100。
您已经体验过将浮点数表示为 double
s 的不精确性。 数字 0.1 不能用二进制精确表示,所以当你在 Java 中说0.1
时,你会得到最接近 0.1
的近似值。 同样的事情也适用于0.05
和0.01
。
您可以执行以下几项操作:
- 尽可能长时间地推迟浮点运算。
例:
total = quarters * 25 + dimes * 10 + nickles * 5 + pennies;
total /= 100.0;
- 使用
DecimalFormat
在两位小数后切断显示。
例:
DecimalFormat df = new DecimalFormat("0.00");
System.out.println("Total $" + df.format(total));
这些解决方法都没有解决基本问题 - double
对数字的不精确表示。 特别是对于金额,不要使用double
. 您甚至可以改用BigDecimal
,其精度是任意的。
我同意你为什么遇到这个问题的解释。对于Java中的这种情况,我推荐的解决方案是使用BigDecimal。它完全可以执行您希望对短小数部分精确的计算。对于不精确的计算,它提供了舍入方法的不错选择。
实际上,它使用比例因子执行整数算术,但自动存储和管理比例。