DecimalFormat Division

Viewed 71
double mny = 0;
mny = Double.parseDouble(JOptionPane.showInputDialog(null, "Enter the amount of Money", "Money Input", JOptionPane.QUESTION_MESSAGE));

//Check for Tens
System.out.println("The # of Tens is " + (int)(mny/10));
mny = mny%10;
System.out.println("The remaining amount of money is " + new DecimalFormat("0.00").format(mny) + " $ ");

//Check for Fives
System.out.println("The # of Fives is " + (int)(mny/5));
mny = mny%5;
System.out.println("The remaining amount of money is " + new DecimalFormat("0.00").format(mny) + " $ ");

//Check for Pennies
System.out.println("The # of Pennies is " + (int)(mny/0.01));
mny = mny%0.01;
System.out.println("The remaining amount of money is " + new DecimalFormat("0.00").format(mny) + " $ ");

If I input 0.01 it gives me 1 penny, but if I input 15.01 it gives me 1 ten 1 five but no penny.
How should I solve this problem?

3 Answers

Because you are assigning the result of each comparison to mny variable, try without them:

double mny = 0;
mny = Double.parseDouble(JOptionPane.showInputDialog(null, "Enter the amount of Money", "Money Input", JOptionPane.QUESTION_MESSAGE));

//Check for Tens
System.out.println("The # of Tens is " + (int)(mny/10));
System.out.println("The remaining amount of money is " + new DecimalFormat("0.00").format(mny % 10) + " $ ");

//Check for Fives
System.out.println("The # of Fives is " + (int)(mny/5));
System.out.println("The remaining amount of money is " + new DecimalFormat("0.00").format(mny % 5) + " $ ");

//Check for Pennies
System.out.println("The # of Pennies is " + (int)(mny/0.01));
System.out.println("The remaining amount of money is " + new DecimalFormat("0.00").format(mny % 0.01) + " $ ");

The issue you see is why it is highly discouraged to use double for monetary values. Use BigDecimal instead.

public static void printCoins(double mny) {
    BigDecimal amount = BigDecimal.valueOf(mny);
    
    //Check for Tens
    BigDecimal[] quotientAndRemainder = amount.divideAndRemainder(BigDecimal.TEN);
    BigDecimal tens = quotientAndRemainder[0].setScale(0);
    amount = quotientAndRemainder[1];
    System.out.println("The # of Tens is " + tens);
    System.out.println("The remaining amount of money is " + amount.setScale(2, RoundingMode.HALF_EVEN) + " $ ");
    
    //Check for Fives
    quotientAndRemainder = amount.divideAndRemainder(BigDecimal.valueOf(5));
    BigDecimal fives = quotientAndRemainder[0].setScale(0);
    amount = quotientAndRemainder[1];
    System.out.println("The # of Fives is " + fives);
    System.out.println("The remaining amount of money is " + amount.setScale(2, RoundingMode.HALF_EVEN) + " $ ");
    
    //Check for Pennies
    quotientAndRemainder = amount.divideAndRemainder(BigDecimal.valueOf(0.01));
    BigDecimal pennies = quotientAndRemainder[0].setScale(0);
    amount = quotientAndRemainder[1];
    System.out.println("The # of Pennies is " + pennies);
    System.out.println("The remaining amount of money is " + amount.setScale(2, RoundingMode.HALF_EVEN) + " $ ");
}

Tests

printCoins(0.01);

printCoins(15.01);

Output

The # of Tens is 0
The remaining amount of money is 0.01 $ 
The # of Fives is 0
The remaining amount of money is 0.01 $ 
The # of Pennies is 1
The remaining amount of money is 0.00 $ 
The # of Tens is 1
The remaining amount of money is 5.01 $ 
The # of Fives is 1
The remaining amount of money is 0.01 $ 
The # of Pennies is 1
The remaining amount of money is 0.00 $ 

The problem you have hit is that floating point number representation is imprecise.

The simplest and easiest way of handling currency is to work with pennies, which are always a whole number, so you can calculate everything using int variables.

This is how banks handle purchase transaction data.

Start with converting user input to an integer number of pennies:

double input = Double.parseDouble(JOptionPane.showInputDialog(null, "Enter the amount of Money", "Money Input", JOptionPane.QUESTION_MESSAGE));
int pennies = (int)(input * 100);

Then the rest of your code needs to be converted to working with pennies, which is straightforward.

Related