Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Something's Wrong With My Code To Calculate Change Money [duplicate]

Tags:

java

So I'm trying to write a code that will help solve this problem:


Develop a Java program that computes which bills and coins will be given as change for a sales transaction.

Available bills are:

$20

$10

$5

$1

Available coins are:

quarter (25 cents)

dime (10 cents)

nickel (5 cents)

penny (1 cent)

Only print the actual bills and coins returned. Do not print unused denominations (for example, if no $10 bills are returned, do not print anything regarding $10 bills).

Example:

What is the total sales charge? 58.12

How much is the customer giving? 100.00

The change is:

2 $20 bills

1 $1 bill

3 quarters

1 dime

3 pennies


Here's the code that I wrote:

    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");
        }


    } }

For the most part, my code seems to work. However, when I input a sales charge of 99.01 and the customer gives 100, I'm missing one penny. I have absolutely no idea what happened to cause that missing penny.

This is what I end up with: 3 quarters 2 dimes 3 pennies

If anyone can help me find the issue, that would be greatly appreciated! I'm only a high school student learning Java so I don't know much...

like image 811
Raymond Tan Avatar asked Feb 06 '23 20:02

Raymond Tan


1 Answers

You're suffering from floating point precision error.

This is the output from your program adding a System.out.println(change); after each while loop.

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           

See how when you get into the change, you don't have nice numbers like .99. You have 0.9899999999999949. This is because the IEEE-754 standard for floating point numbers has some limitations, which cause slight amounts of error for any decimal that can't be represented in terms of powers of 2. Usually, the error is too small to cause problems, but you happened to find a test case where you suffered from it.

So what can you do? The easiest solution in my opinion would be to convert your input to all integers and keep track of numbers in terms of pennies, instead of of dollars. That would avoid the floating point precision issue.

Other languages, such as C#, actually provide a different data type from float or double specifically for dealing with numbers that require precision in base-10 numbers. C#'s, for example, is decimal. I am not aware of an equivalent in Java, so this is something you have to keep in mind when working with any floating point number

As another example of the horrors of floating point error, what would you expect this to print?

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

Make your guess, then check your answer...

like image 67
Tyler Lee Avatar answered May 10 '23 23:05

Tyler Lee