Join 132,638 Java Programmers for FREE! Get instant access to thousands of Java experts, tutorials, code snippets, and more! There are 1,073 people online right now. Registration is fast and FREE... Join Now!
This is a virtual soda machine. I have been working on the method that gives coin change for 4 hours and can't see the error. Any help is appreciated. Here is some output:
Hey! Buy a beverage!
The temperature is: 70.6 degrees fahrenheit outside.
The cost of your beverage is: $0.75
Please enter the amount of money you wish to insert; please insert no more than one dollar and no pennies: .85
You entered: $0.85
Your change is: $0.10
Your coin return is: no quarters no dimes 1 nickel
Thank you for your money.
CODE
//************************************************************************** // // // //************************************************************************** public class SodaTester { public static void main (String[] args)
{ SodaMachine soda = new SodaMachine(); soda.getTemp(); soda.tellPrice(); soda.getMoney(); soda.GiveChangeOrNoSale(); } }
public class SodaMachine { double temp, price, cash, change, numQuarters, numDimes, numNickels;
Scanner scan = new Scanner (System.in);
public void getTemp() { temp = (double)(Math.random () * 61 + 40); System.out.println ("Hey! Buy a beverage!"); System.out.println (); DecimalFormat fmt = new DecimalFormat ("0.#"); System.out.println ("The temperature is: " + fmt.format(temp) + " degrees fahrenheit outside."); System.out.println (); }
public void tellPrice() { if (temp <= 40) { System.out.println ("Why the heck would you want a soda at a temperature below 40 degrees fahrenheit? You idiot!"); System.out.println ("No Sale"); } if (temp <= 50) { price = .50; } else if (temp <= 60) { price = .55; } else if (temp <= 65) { price = .60; } else if (temp <= 70) { price = .70; } else if (temp <= 75) { price = .75; } else if (temp <= 80) { price = .80; } else if (temp <= 85) { price = .85; } else if (temp <= 90) { price = .90; } else if (temp <= 100) { price = 1.00; } else { System.out.println ("It's over 100 degrees out: go buy an air conditioner."); System.out.println ("No Sale"); } NumberFormat money = NumberFormat.getCurrencyInstance(); System.out.println ("The cost of your beverage is: " + money.format(price)); System.out.println (); }
public void getMoney() { System.out.println ("Please enter the amount of money you wish to insert; please insert no more than one dollar and no pennies: "); cash = scan.nextDouble(); System.out.println (); }
System.out.println (); System.out.println ("Thank you for your money."); } else { System.out.println ("Not acceptable; you do not have adequate funding for this investment."); System.out.println (); }
}
}
This post has been edited by notpro1: 12 Oct, 2008 - 09:34 AM
This is because Java's double data type precision is off a bit. Instead of .65 - .55 being .10 it is coming out as .0999999999998. The result is that when you take this number and modulus it by .10 you are going to get 0 for dimes, that number then carries over to nickle where again .05 only goes into .0999999999998 once and hence the 1 nickle output.
To fix this you are going to have to use a different data type like BigDecimal or multiple your values by 100, divide by integers, then display again as a double which might be your easiest bet.
So as they enter the value .65, you multiply it by 100 so you get 65 and lets say the pop is .75, that too is multiplied by 100 so you get 75 - 65 = 10. Take that 10 and run it through where you divide/modulus it by 25 (not .25), divide/modulus it by 10 (not .10) and nickles to get your correct change.
However you tackle it know the problem is because of how double handles some rounding of decimal values.
Hey, thanks. wow, I would have never thought of that. This is my 5th week in HighSchool AP computerscience A. My teacher is really difficult. Thanks Again, I'll adjust myprogram and post it
K, I tried what you told me but it still prints out the wrong change. any ideas
here's the output: Hey! Buy a beverage!
The temperature is: 82.2 degrees fahrenheit outside.
The cost of your beverage is: $0.85
Please enter the amount of money you wish to insert; please insert no more than one dollar and no pennies: .95
You entered: $0.95
Your change is: $0.10
Your coin return is: no quarters no dimes no nickels
Thank you for your money.
and the code:
CODE
//************************************************************************** // // // //************************************************************************** public class SodaTester { public static void main (String[] args)
{ SodaMachine soda = new SodaMachine(); soda.getTemp(); soda.tellPrice(); soda.getMoney(); soda.GiveChangeOrNoSale(); } }
public class SodaMachine { double temp, price, cash, change, numQuarters, numDimes, numNickels;
Scanner scan = new Scanner (System.in);
public void getTemp() { temp = (double)(Math.random () * 61 + 40); System.out.println ("Hey! Buy a beverage!"); System.out.println (); DecimalFormat fmt = new DecimalFormat ("0.#"); System.out.println ("The temperature is: " + fmt.format(temp) + " degrees fahrenheit outside."); System.out.println (); }
public void tellPrice() { if (temp <= 40) { System.out.println ("Why the heck would you want a soda at a temperature below 40 degrees fahrenheit? You idiot!"); System.out.println ("No Sale"); } if (temp <= 50) { price = .50; } else if (temp <= 60) { price = .55; } else if (temp <= 65) { price = .60; } else if (temp <= 70) { price = .70; } else if (temp <= 75) { price = .75; } else if (temp <= 80) { price = .80; } else if (temp <= 85) { price = .85; } else if (temp <= 90) { price = .90; } else if (temp <= 100) { price = 1.00; } else { System.out.println ("It's over 100 degrees out: go buy an air conditioner."); System.out.println ("No Sale"); } NumberFormat money = NumberFormat.getCurrencyInstance(); System.out.println ("The cost of your beverage is: " + money.format(price)); System.out.println (); }
public void getMoney() { System.out.println ("Please enter the amount of money you wish to insert; please insert no more than one dollar and no pennies: "); cash = scan.nextDouble(); System.out.println (); }
System.out.println (); System.out.println ("Thank you for your money."); } else { System.out.println ("Not acceptable; you do not have adequate funding for this investment."); System.out.println (); }
Hey!!! I finally figured it out. It took me 'til now to realize it and it works. This was a realllll brainbuster and I'm particularly proud for having thought of it. What you mentioned about the changing to int didn't work but then I thought ... and thought ... about the .9999999999998. If this was the error, and I don't want the user to enter more than a dollar, then why not do this tricky piece of coding
CODE
System.out.println ("Your change is: " + money.format(change)); System.out.println ();
Another option is to use pennies. Computers generally suck at floating point and usually can't be trusted with it.
Then I thought, wait a minute, since when does a change machine know how to divide? Changed machines are dumb as dirt, they increment and decrement and that's all they need to do. Floating point is killing a fly with a hammer...
Here's one way to do it.
java
void giveChange(double changeDbl) { System.out.print("Change due amount: "); System.out.println(java.text.NumberFormat.getCurrencyInstance().format(changeDbl));
int change = (int)(changeDbl * 100); System.out.print("Change: "); while (change>0) { if (change>=25) { change -= 25; System.out.print ("quarter"); } else if (change>=10) { change -= 10; System.out.print ("dime"); } else if (change>=5) { change -= 5; System.out.print ("nickel"); } else if (change>=1) { change -= 1; System.out.print ("penny"); } if (change>0) { System.out.print (", "); } } System.out.println(); }