Reputation: 1
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 ");
}
}
Upvotes: 0
Views: 287
Reputation:
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
i1 = 3227
i2 = 3600
rad = -372
rai = -373
rdd = -3.73
ndi = -3
Upvotes: 0
Reputation: 43738
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.
Upvotes: 1
Reputation: 200168
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.
Upvotes: 1
Reputation: 14061
Calculations of this type should never use primitive types. Always use BigDecimal
.
Upvotes: 0