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...
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...
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With