所以我正在尝试编写一个有助于解决这个问题的代码:
开发一个Java程序,计算哪些账单和硬币将作为销售交易的变更。
可用账单是:
港币$ 160
10 $
$ 5'/ P>
$ 1
可用的硬币是:
季度(25美分)
一角钱(10美分) 镍(5美分) 便士(1美分)仅打印退回的实际账单和硬币。不要打印未使用的面额(例如,如果没有退回10美元的账单,不要打印任何关于10美元账单的东西)。
示例:
总销售费用是多少? 58.12
客户给予多少钱? 100.00
改变是:
2 20美元的账单
1 $ 1 bill
3个季度
1角钱
3便士
这是我写的代码:
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner uinput = new Scanner(System.in);
double paid;
double cost;
double change;
int onebills = 0;
int fivebills = 0;
int tenbills = 0;
int twentybills = 0;
int quarters = 0;
int dimes = 0;
int nickels = 0;
int pennies = 0;
System.out.println("What is the total sales charge?");
cost = uinput.nextDouble();
System.out.println("");
System.out.println("How much is the customer giving?");
paid = uinput.nextDouble();
change = paid - cost;
while(change >= 20) { //if the change is more than $20, give a 20 dollar bill
change -= 20;
twentybills++;
}
while(change >= 10) { //if the change is more than $10, give a 10 dollar bill
change -= 10;
tenbills++;
}
while(change >= 5) { //if the change is more than $5, give a 5 dollar bill
change -= 5;
fivebills++;
}
while(change >= 1) { //if the change is more than $1, give a 1 dollar bill
change -= 1;
onebills++;
}
while(change >= 0.25) { //if the change is more than $0.25, give a quarter
change -= 0.25;
quarters++;
}
while(change >= 0.10) { //if the change is more than $0.10, give a dime
change -= 0.10;
dimes++;
}
while(change >= 0.05) { //if the change is more than $0.05, give a nickel
change -= 0.05;
nickels++;
}
while(change >= 0.01) { //if the change is more than $0.01, give a penny
change -= 0.01;
pennies++;
}
System.out.println("");
if(twentybills > 0) {
System.out.println(twentybills + " twenty dollar bills");
}
if(tenbills > 0) {
System.out.println(tenbills + " ten dollar bills");
}
if(fivebills > 0) {
System.out.println(fivebills + " five dollar bills");
}
if(onebills > 0) {
System.out.println(onebills + " one dollar bills");
}
if(quarters > 0) {
System.out.println(quarters + " quarters");
}
if(dimes > 0) {
System.out.println(dimes + " dimes");
}
if(nickels > 0) {
System.out.println(nickels + " nickels");
}
if(pennies > 0) {
System.out.println(pennies + " pennies");
}
} }
在大多数情况下,我的代码似乎有效。但是,当我输入99.01的销售费用并且客户给出100时,我错过了一分钱。我完全不知道发生了什么导致那个丢失的便士。
这就是我最终的结果: 3季度 2角钱 3便士
如果有人可以帮我找到问题,那将非常感谢!我只是一个学习Java的高中生,所以我不太了解......
答案 0 :(得分:7)
您正遭受浮点精度错误。
这是您的程序添加System.out.println(更改)的输出;在每个while循环之后。
How much is the customer giving?
100
0.9899999999999949
0.9899999999999949
0.9899999999999949
0.9899999999999949
0.23999999999999488
0.03999999999999487
0.009999999999994869
3 quarters
2 dimes
3 pennies
了解当你进入变革时,你不会有像.99这样的好数字。你有0.9899999999999949。这是因为浮点数的IEEE-754标准有一些限制,这会导致任何小数的误差很小,无法用2的幂表示。通常,误差太小而不能导致问题,但你碰巧找到了一个你遭受它的测试用例。
那你能做什么?在我看来,最简单的解决方案是将输入转换为所有整数,并以便士而不是美元来跟踪数字。这样可以避免浮点精度问题。
其他语言(例如C#)实际上提供了来自float
或double
的不同数据类型,专门用于处理需要基数为10的数字的数字。例如,C#是decimal
。我不知道Java中的等价物,所以在使用任何浮点数时你必须记住这一点
作为浮点错误恐怖的另一个例子,您希望打印什么?
if(.1 + .2 == .3)
System.out.println("TRUE");
else
System.out.println("FALSE");
猜猜,然后check your answer ...