Java 某物';我计算零钱的代码有问题吗

Java 某物';我计算零钱的代码有问题吗,java,Java,因此,我试图编写一个代码来帮助解决这个问题: 开发一个Java程序,计算在销售交易中哪些纸币和硬币将作为零钱提供 可供选择的帐单有: 20美元 10美元 五美元 一美元 可用硬币有: 四分之一(25美分) 一角硬币(10美分) 镍(5美分) 便士(1美分) 仅打印返回的实际纸币和硬币。不要打印未使用的面额(例如,如果没有退回10美元的钞票,不要打印任何有关10美元钞票的内容) 例如: 销售总费用是多少? 58.12 顾客给多少钱? 100.00 变化是: 2张20美元的钞票 一元一张的钞票 四

因此,我试图编写一个代码来帮助解决这个问题:


开发一个Java程序,计算在销售交易中哪些纸币和硬币将作为零钱提供

可供选择的帐单有:

20美元

10美元

五美元

一美元

可用硬币有:

四分之一(25美分)

一角硬币(10美分)

镍(5美分)

便士(1美分)

仅打印返回的实际纸币和硬币。不要打印未使用的面额(例如,如果没有退回10美元的钞票,不要打印任何有关10美元钞票的内容)

例如:

销售总费用是多少? 58.12

顾客给多少钱? 100.00

变化是:

2张20美元的钞票

一元一张的钞票

四分之三

一角

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便士


如果有人能帮我找到这个问题,我将不胜感激!我只是一名学习Java的高中生,所以我知道的不多…

您正遭受浮点精度错误的折磨

这是程序添加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.9899999949。这是因为浮点数的标准有一些限制,对于任何不能用2的幂表示的十进制数,都会产生轻微的误差。通常,错误太小而不会引起问题,但是您碰巧发现了一个测试用例,您正是在这个测试用例中遇到了问题

那你能做什么呢?在我看来,最简单的解决方案是将您的输入转换为所有整数,并以便士而不是美元来跟踪数字。这将避免浮点精度问题

其他语言,如C#,实际上提供了与
float
double
不同的数据类型,专门用于处理要求精度为10进制的数字。例如,C#的值是
十进制
。我不知道Java中有一个等价物,所以在处理任何浮点数时都必须记住这一点

作为浮点错误可怕的另一个例子,您希望打印什么

if(.1 + .2 == .3)
  System.out.println("TRUE");
else
  System.out.println("FALSE");

猜猜看……

你试过调试吗?为什么投反对票?我认为他才刚刚开始,我很肯定,他并不是天生就懂得如何写出好的问题。虽然这个问题也不是很糟糕,但调试是一个逐行跟踪代码执行的过程,以查看实际发生的情况。这是开始编写代码时需要掌握的最重要的技能之一。请参阅使用Eclipse的简短视频教程。毫无疑问,问题在于舍入错误。这里有一个页面可能与此相关(我没有运行您的代码,因此也可能不相关):。要添加到这个答案上,一个简单的修复方法就是将输入乘以100,然后再进行所有后续检查。即,
cost=uinput.nextout()*100
而不是
cost=uinput.nextDouble()
while(change>=500)
而不是
while(change>=5)
。注意我们现在是如何使用整数的,所以相应地调整变量。@EdwardShen这正是我们建议的。另一个选择是使用
BigDecimal
。快告诉我:)我会删除我的答案,然后给你的投票@shmosel我发布的评论是针对原始海报的,而不是回答者。很抱歉造成任何混乱。@EdwardShen,您仍然需要使用
nextDouble()
,因为用户可能会输入熟悉的美元.cents符号。