Change Calculator Subtracting One - java

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:

Related

Logical Error Java - Wrong Computation in BMI

The program lets you input the user's height and weight then outputs the BMI and associated health risk. It converts pounds to kilograms. It also converts the height in feet and inches to meters.
Scanner scanW = new Scanner (System.in);
Scanner scanH = new Scanner (System.in);
System.out.println("Enter your weight in pounds: ");
int weight = scanW.nextInt();
System.out.println("Enter your height in feet followed \nBy a space then additional inches");
String height = scanH.nextLine();
scanW.close();
scanH.close();
int heightFt = height.charAt(0);
int heightInch = height.charAt(2);
int finalHeightFeet = Integer.parseInt(String.valueOf(heightFt));
int finalHeightInch = Integer.parseInt(String.valueOf(heightInch));
double mass = (double) weight / 2.2;
double finalHeight = (double) (finalHeightFeet * 0.3048) + (finalHeightInch * 0.0254);
double BMI = (double) mass / (finalHeight * finalHeight);
System.out.println("Your BMI is " +BMI);
if (BMI < 18.5)
System.out.println("Your risk category is UnderWeight");
else if (BMI < 25)
System.out.println("Your risk category is Normal Weight");
else if (BMI < 30)
System.out.println("Your risk category is Normal Overweight");
else if (BMI >= 30)
System.out.println("Your risk category is Obese");
the correct BMI and risk category output should be:
Your BMI is 25.013498117367398
Your risk category is Overweight.
but my output would be like this:
Your BMI is 0.22261924276759873
Your risk category is UnderWeight
I'm very sure there's a problem in my formula but I can't seem to find it. Would be very helpful if someone pointed out which is wrong
You are not parsing the height input correctly.
Suppose you type
5 9
as the height.
You assign "5 9" to height.
You then parse
int heightFt = height.charAt(0);
int heightInch = height.charAt(2);
which assigns 53 to heightFt and 57 to heightInch (those are the numeric values of the characters '5' and '9').
Try this instead:
String[] height = scanH.nextLine().split (" ");
int heightFt = Integer.parseInt (height[0]);
int heightInch = Integer.parseInt (height[1]);
You are parsing the chars which are represented in numerical values.
Take a look on ASCII TABLE.
For example, if you will put 6 2 as height, the result is actually 54 for 6, 32 for space, and 50 for 2.
scanW.close(); // these two are not necessary
scanH.close();
int heightInch = height.charAt(2); // what if the person is 5' 11" ?
I modified your code a bit, take a look.
Scanner scanW = new Scanner (System.in);
Scanner scanH = new Scanner (System.in);
System.out.println("Enter your weight in pounds: ");
int weight = scanW.nextInt();
System.out.println("Enter your height in feet followed \nBy a space then additional inches");
String height = scanH.nextLine();
int feets = Integer.parseInt(height.substring(0,1));
// get all the chars after index 2
int inches = Integer.parseInt(height.substring(2));
int totalInches = feets * 12 + inches;
double BMI = weight/Math.pow(totalInches, 2) * 703;
System.out.println("BMI: "+BMI);
System.out.println("Enter your weight in pounds: ");
int weight = scan.nextInt();
System.out.println("Enter your height in feet followed \nBy a space then additional inches");
int heightFt = scan.nextInt();
int heightInch = scan.nextInt();
scan.close();
double finalMass = weight / 2.2;
double finalHeight = (heightFt * 0.3048) + (heightInch * 0.0254);
double BMI = finalMass / (finalHeight * finalHeight);
System.out.println("Your BMI is " +BMI);
if (BMI < 18.5)
System.out.println("Your risk category is UnderWeight");
else if (BMI < 25 && BMI >= 18.5)
System.out.println("Your risk category is Normal Weight");
else if (BMI < 30 && BMI >= 25)
System.out.println("Your risk category is Overweight");
else
System.out.println("Your risk category is Obese");

I'm making a payroll using Java. Why am I getting the wrong net pay if my mathematical formulas seem correct?

I'm making a payroll calculator. The first person worked 38.00 hours with a pay rate of $8.75. The second person worked 46.50 hours with a pay rate of $17.00. It's obvious the second person worked overtime. I'm experiencing issues when calculating the net pay as well as the gross pay. The second person's net pay should be $718.89. I keep getting $140.89. The issues only happen if the person works overtime (>40). Is there a problem with my if statement? I'd like some advice. I've been learning Java for 2 weeks now, excuse the mistakes.
package com.company;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
final byte PERCENT = 15;
// Tax is 15%
final float taxRate = PERCENT / (float) 100;
Scanner scanner = new Scanner(System.in);
System.out.print("First Name: ");
String firstName = scanner.next().trim();
System.out.print("Last Name: ");
String lastName = scanner.next().trim();
System.out.println(lastName + ", " + firstName);
System.out.print("Pay Rate: ");
float payRate = scanner.nextFloat();
System.out.print("Hours Worked: ");
float totalHours = scanner.nextFloat();
// regular hours = total hours if less than 40
// overtime = total hours - 40
float regularPay = 0;
if (totalHours <= 40) {
regularPay = totalHours * payRate;
}
float overTimePay = 0;
if (totalHours > 40) {
overTimePay = (float) ((totalHours - 40) * 1.5 * payRate);
}
final double grossPay = (double) regularPay + (double) overTimePay;
System.out.println("Gross Pay: " + (Math.round(grossPay * 100.0) / 100.0));
final double taxAmount = grossPay * taxRate;
System.out.println("Tax Amount: " + (Math.round(taxAmount * 100.0) / 100.0));
final double netPay = grossPay - taxAmount;
System.out.println("Net Pay: " + (Math.round(netPay * 100.0) / 100.0));
}
}
if totalHours > 40, regularPay will be 0 in your code.
you should change the condition to something like this.
if totalHours > 40, first calculate regularPay for 40 hours
overtimepay should be remaining hours (totalhours -40)
your regularPay variable is only being recorded if hours<=40. You need to put something in your second if statement to set your regularPay variable. You probably want something like:
regularPay = 40*payRate;
Include this in your second if statement

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!

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

Odd accuracy error 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);.

Categories