我的代码计算更改资金有些不对劲

时间:2016-06-08 22:25:35

标签: java

所以我正在尝试编写一个有助于解决这个问题的代码:

开发一个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的高中生,所以我不太了解......

1 个答案:

答案 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#)实际上提供了来自floatdouble的不同数据类型,专门用于处理需要基数为10的数字的数字。例如,C#是decimal。我不知道Java中的等价物,所以在使用任何浮点数时你必须记住这一点

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

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

猜猜,然后check your answer ...