Odd accuracy error Java - java

Currently I am attempting to write a change machine in java. For some reason there is a large loss in accuracy during conversion.
It will first ask for the data values of how much is owed and how much is paid. Then it will divide out the numbers of quarters and mod out the remainder. Then it will perform this with dimes, nickles, and then pennies. After this it will then print out how much change is owed.
import java.io.*;
import static java.lang.System.*;
import java.util.Scanner;
class change{
public static void main (String str[]) throws IOException {
//asker thingy
Scanner scan = new Scanner(System.in);
System.out.println("Please enter the Cost of the Item:");
System.out.print("$");
double costowed = scan.nextDouble();
System.out.println("Please Enter the Amount Payed:");
System.out.print("$");
double costpayed = scan.nextDouble();
//Quarters
double a1 = Math.round( (costpayed - costowed) * 100);
int quarters = (int)(a1 / 25);
int a2 = (int)(a1 % 25);
//dimes
int dimes = (int)(a2 / 10);
int a3 = (int)(a1 % 10);
//nickles & pennies
int nickles = (int)(a3 / 5);
int pennies = (int)(a1 % 5);
//change owed
double arc = (double)(a1 / 100);
//print sequence
System.out.println("Change owed: " + arc);
System.out.println("Quarters: " + quarters);
System.out.println("Dimes: " + dimes);
System.out.println("Nickles: " + nickles);
System.out.println("Pennies: " + pennies);
}
}

The line
int a3 = (int)(a1 % 10);
should be:
int a3 = (int)(a2 % 10);
And likewise int pennies = (int)(a1 % 5); should be int pennies = (int)(a3 % 5);.

Related

Why does my program only provide change in dollar amounts?

This is my current code:
import java.util.Scanner;
public class CustomerChange {
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
double cost = 0.00;
double cash = 0.00;
double dollars = 0.00;
System.out.println("Price: ");
cost = scanner.nextDouble();
System.out.println("Cash: ");
cash = scanner.nextDouble();
if (cash < cost) {
System.out.println("Not enough cash. Goodbye.");
}
else if (cash > cost) {
dollars = cash - cost;
System.out.println("\nChange: \n");
if ((int) dollars / 20 > 0) {
System.out.println("Twenties: " + (int) dollars / 20);
dollars %= 20;
}
if ((int) dollars / 10 > 0) {
System.out.println("Tens: " + (int) dollars / 10);
dollars %= 10;
}
if ((int) dollars / 5 > 0) {
System.out.println("Fives: " + (int) dollars / 5);
dollars %= 5;
}
if ((int) dollars / 1 > 0) {
System.out.println("Ones: " + (int) dollars / 1);
dollars %= 1;
dollars *= 100;
}
if ((int) dollars / 25 > 0) {
System.out.println("Quarters: " + (int) dollars / 25);
dollars %= 25;
}
if ((int) dollars / 10 > 0) {
System.out.println("Dimes: " + (int) dollars / 10);
dollars %= 10;
}
if ((int) dollars / 5 > 0) {
System.out.println("Nickels: " + (int) dollars / 5);
}
if ((int) dollars / 1 > 0) {
System.out.println("Pennies: " + (int) dollars / 1);
}
} else if (cash == cost) {
System.out.println("Thank you. Goodbye.");
}
scanner.close();
}
}
Right now, when I enter in a price of 3.25 and a cash of 4, I don't get a return of my change, but when I enter in a price of 168.75 and a cash of 200, I get:
Price:
168.75
Cash:
200
Change:
Twenties: 1
Tens: 1
Ones: 1
Quarters: 1
Where am I going wrong? It took forever to figure out the math and I thought that was the crux but I guess not?
When you are inputting: Price: 3.25 and Cash: 4
(int)(0.75) will be 0.
So it will not get inside any of the if block.
Put a condition like
if ((int) dollars / 1 == 0) {
System.out.println("Pennies: " + (int)(dollars*100));
}
Then it will definitely work.
Your code is overly complicated due to attempting to work with double instead of just converting everything to an integer to begin with. This way everything is in the value of pennies, and you do not need to worry about any casting or multiplying a decimal later on by 100 in order to work with the coins, and the code will be less prone to bugs.
Here is what it would look like using similar logic you were using, but instead if in the form of pennies (you don't even need the if statements):
public static void main(String[] args) {
Scanner scanner = new Scanner(System.in);
int pricePennies = 0;
int cashPennies = 0;
System.out.println("Price: ");
pricePennies = (int) (scanner.nextDouble() * 100);
System.out.println("Cash: ");
cashPennies = (int) (scanner.nextDouble() * 100);
if (cashPennies < pricePennies) {
System.out.println("Not enough cash. Goodbye.");
}
else if (cashPennies > pricePennies) {
int change = cashPennies - pricePennies;
System.out.println("Twenties: " + change / 2000);
change %= 2000;
System.out.println("Tens: " + change / 1000);
change %= 1000;
System.out.println("Fives: " + change / 500);
change %= 500;
System.out.println("Ones: " + change / 100);
change %= 100;
System.out.println("Quarters: " + change / 25);
change %= 25;
System.out.println("Dimes: " + change / 10);
change %= 10;
System.out.println("Nickels: " + change / 5);
change %= 5;
System.out.println("Pennies: " + change / 1);
change %= 1;
}
else if (cashPennies == pricePennies) {
System.out.println("Thank you. Goodbye.");
}
scanner.close();
}
Test Runs:
Price:
168.75
Cash:
200
Twenties: 1
Tens: 1
Fives: 0
Ones: 1
Quarters: 1
Dimes: 0
Nickels: 0
Pennies: 0
Price:
3.25
Cash:
4
Twenties: 0
Tens: 0
Fives: 0
Ones: 0
Quarters: 3
Dimes: 0
Nickels: 0
Pennies: 0
Price:
54748
Cash:
63939.46
Twenties: 459
Tens: 1
Fives: 0
Ones: 1
Quarters: 1
Dimes: 2
Nickels: 0
Pennies: 1

Change Calculator Subtracting One

My calculator in Java will not output the correct amount of change. It subtracts one penny and I am not sure why.
I initially declared the change as separate variables but I then just multiplied the users input by 100, but I still have the same problem.
//this is where the variables are declared
double penny = 0.01;
double nickel = 0.05;
double dime = 0.10;
double quarter = 0.25;
double half_dollar = 0.50;
double dollar_coin = 1.00;
double user_input = 0;
int total_penny, total_nickel, total_dime, total_quarter,
total_half_dollar, total_dollar_coin;
Scanner in = new Scanner (System.in);
//this is where the user can input data
System.out.println("What amount would you like change for: ");
user_input = in.nextDouble();
//this is where the users data will be processed
total_dollar_coin = (int) (user_input / 1.0);
user_input = user_input % 1.00;
total_half_dollar = (int) (user_input / 0.50);
user_input = user_input % 0.50;
total_quarter = (int) (user_input / 0.25);
user_input = user_input % 0.25;
total_dime = (int) (user_input / 0.10);
user_input = user_input % 0.10;
total_nickel = (int) (user_input / 0.05);
user_input = user_input % 0.01;
total_penny = (int) (user_input / 0.01);
//this is where the information will be outputted to the user
System.out.println("Your change will be: " + total_dollar_coin + " dollar
coin(s) ");
System.out.println(total_half_dollar + " half dollar coin(s) " +
total_quarter
+ " quarter(s) ");
System.out.print(total_dime + " dime(s) " + total_nickel + " nickel(s) " +
total_penny + " penny (or pennies) ");
}
}
If you debug this, you will see that for e.g. 51.43 your last line:
total_penny = (int) (user_input / 0.01);
results in something like:
Since you are casting to int, this will result in "unexpected output", in this case zero (0) - see link provided above in the second comment regarding accuracy.
Nonetheless, a possible solution to the problem (as an educational exercise) is to do the following:
BigDecimal total_penny;
int total_nickel, total_dime, total_quarter, total_half_dollar, total_dollar_coin;
And then in your total_penny line:
user_input = user_input % 0.05; --> you have 0.01 typo here
total_penny = BigDecimal.valueOf(user_input / 0.01);
Format the total_penny output and output that:
String penny = NumberFormat.getInstance().format(total_penny);
System.out.println("..." + penny + " penny (or pennies) ");
This will give you the amount you expect:

I'm not sure how to round this properly in my Java code

I'm fairly new to Java, and I've recently written a code that calculates how much change you would need for x amount of money payed for a y priced item. It works well; my only issue is that whenever there is not any change owed in the hundredths place (ex: $4.60), it will round down to the tenths place ($4.6).
If anybody knows how to fix this, I would be very grateful. I have the code posted below.
class Main {
public static void main(String[] args) throws IOException {
Scanner scan = new Scanner(System.in);
double x;
double y;
double z;
System.out.print("Enter the price of the product: $");
x = scan.nextDouble();
System.out.print("Enter what you payed with: $");
y = scan.nextDouble();
z = (int)Math.round(100*(y-x));
System.out.print("Change Owed: $");
System.out.println((z)/100);
int q = (int)(z/25);
int d = (int)((z%25/10));
int n = (int)((z%25%10/5));
int p = (int)(z%25%10%5);
System.out.println("Quarters: " + q);
System.out.println("Dimes: " + d);
System.out.println("Nickels: " + n);
System.out.println("Pennies: " + p);
}
}
Edit: Thank you to everyone that answered my question! I ended up going with DecimalFormat to solve it, and now it works great.
You can call something like this:
String.format("%.2f", i);
So in your case:
...
System.out.print("Change Owed: $");
System.out.println((String.format("%.2f", z)/100));
...
String.format() is useful whenever you want to round it to certain significant figures. In this case "f" stands for float.
This behavior is expected. You do not want numbers to carry trailing zeroes.
You can use DecimalFormat for representing them as a String with a trailing zero, rounded to two digits.
Example:
DecimalFormat df = new DecimalFormat("#0.00");
double d = 4.7d;
System.out.println(df.format(d));
d = 5.678d;
System.out.println(df.format(d));
Output:
4.70
5.68
You can also add your currency sign to the DecimalFormat:
DecimalFormat df = new DecimalFormat("$#0.00");
Output with currency sign:
$4.70
$5.68
EDIT:
You can even tell DecimalFormat how to round your number by setting the RoundingMode through df.setRoundingMode(RoundingMode.UP);
The String.format() method is my personal preference. For example:
float z;
System.out.println(String.format("Change Owed: $%.2f", (float) ((z) / 100)));
%.2f will round any float ('f' stands for float) off to 2 decimal places, by changing the number before the 'f' you change how many decimal points you round to. Eg:
//3 decimal points
System.out.println(String.format("Change Owed: $%.3f", (float) ((z) / 100)));
//4 decimal points
System.out.println(String.format("Change Owed: $%.4f", (float) ((z) / 100)));
// and so forth...
You may want to do some reading into String.format() if you are starting out with Java. It is a very powerful and useful method.
From what I understand:
public static void main(String[] args) throws IOException {
Scanner scan = new Scanner(System.in);
double x;
double y;
double z;
System.out.print("Enter the price of the product: $");
x = scan.nextDouble();
System.out.print("Enter what you payed with: $");
y = scan.nextDouble();
z = (int) Math.round(100 * (y - x));
System.out.println(String.format("Change Owed: $%.2f", (float) ((z) / 100)));
int q = (int) (z / 25);
int d = (int) ((z % 25 / 10));
int n = (int) ((z % 25 % 10 / 5));
int p = (int) (z % 25 % 10 % 5);
System.out.println("Quarters: " + q);
System.out.println("Dimes: " + d);
System.out.println("Nickels: " + n);
System.out.println("Pennies: " + p);
}
All the best for your future projects!

Convertiny Monetary Units

I got the dollars to work but now I can`t figure out how to display the quarters, dimes, nickels, and pennies correctly. Technically they show up but my professor wants $1.35 to show up as 1 dollar 1 quarter and 1 dime. But, mine shows up as 1 dollars 5 Quarters 13 Dimes 27 Nickels 135 Pennies. Here is my code:
import java.util.Scanner;
public class ComputeChange {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Enter an amount in double, for example 11.56: " );
double number = input.nextDouble();
System.out.println("Your amount " + number + " consists of ");
int remainingamount = (int)(number*100);
int Quarters = remainingamount/25;
int Dimes = remainingamount/10;
int Nickels = remainingamount/5;
int Pennies = remainingamount;
if (number == 1) {
System.out.print("1 dollar ");
}
else if (number > 1) {
System.out.print((int)number + " dollars ");
}
if (number == 0) {
System.out.println("");
}
System.out.print(Quarters + " Quarters " + Dimes + " Dimes " + Nickels + " Nickels " + Pennies + " Pennies");
}
}
For each different coin you calculate, you need to remove this from the remaining amount. Such as (untested):
int Dollars = (int)number;
int remainingamount = (int)((number-Dollars)*100);
int Quarters = remainingamount/25;
remainingamount -= Quaters * 25;
int Dimes = remainingamount/10;
remainingamount -= Dimes * 10
int Nickels = remainingamount/5;
remainingamount -= Nickels * 5
int Pennies = remainingamount;
Since you're using Java, have you tried JSR 354?
See JavaMoney.org or the JSR 354 Detail page at JCP.org It offers standard API for the conversion of monetary units and default exchange rate providers by the IMF or European Central Bank.

Why does it keep rounding down to two cents on my java change/cashier program?

I have tried many ways like math.Round and making them doubles and ints but i have no idea why and where it rounds down to 2 cents at the end. When i purchase 32.27 and pay with 36 the answer is 3 dollars 2 quarters 2 dimes 2 cents.
here is my code:
import java.util.Scanner;
public class Change {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
System.out.print("Purchase: ");
double purchase = input.nextDouble();
System.out.print("Payment: ");
double amountGiven = input.nextDouble();
int remainingAmount = (int) ((amountGiven - purchase) * 100);
int numOfDollars = remainingAmount / 100;
remainingAmount = remainingAmount % 100;
int numOfQuarters = remainingAmount / 25;
remainingAmount = remainingAmount % 25;
int numOfDimes = remainingAmount / 10;
remainingAmount = remainingAmount % 10;
int numOfPennies = remainingAmount;
System.out.println("Given $ " + amountGiven + " for a purchase of $ " +
purchase + " we need " + numOfDollars + " dollars " + numOfQuarters +
" quarters " + numOfDimes + " dimes " +
numOfPennies + " cents ");
}
}
If you run this code, you'll see where your problem is:
final double purchase = 32.27;
System.out.println("Purchase: " + new BigDecimal(purchase));
final double diff = 36 - purchase;
System.out.println("Difference: " + new BigDecimal(diff));
System.out.println("Cent difference: " + (int)(100*diff));
The output will be
Purchase: 32.27000000000000312638803734444081783294677734375
Difference: 3.72999999999999687361196265555918216705322265625
Cent difference: 372
So you can see that your trouble starts right off the bat: the decimal value 32.27 is represented by the nearest double value, which is slightly larger. The difference is then slightly less, which after truncation drops a whole cent.
Lesson: don't parse the input into a double, but into a BigDecimal.
This happens, because the amount cannot be represented exactly as a double. When you convert to an int it gets truncated.
The change amount in cents is 372.99999999999955 if you print it with 14 decimals.
Either use BigDecimal or a custom Currency type that only uses Integer or int to do calculations.
Calculations of this type should never use primitive types. Always use BigDecimal.
You can't do division that results in remainders on integer types without losing precision
double d1 = 32.27;
double d2 = 36;
int i1 = (int) (d1 * 100);
int i2 = (int) (d2 * 100);
int rad = (int) ((d1 - d2 ) * 100);
int rai = i1 - i2;
double rdd = (double)rai / 100; // <- this is what you are expecting
int ndi = rai / 100;
// ^ this is what you are getting
// int / int == double which gets silently truncated
System.out.println("i1 = " + i1);
System.out.println("i2 = " + i2);
System.out.println("rad = " + rad);
System.out.println("rai = " + rai);
System.out.println("rdd = " + rdd); // mostly accurate in this case
System.out.println("ndi = " + ndi); // truncated
Ouputs
i1 = 3227
i2 = 3600
rad = -372
rai = -373
rdd = -3.73
ndi = -3

Categories