-2

why does java turn a number that would otherwise be 10 into something like 9.999999999999998? here is my code. also, any suggestions on good practice would be appreciated. for example, what i can do in place of all the if statements. the purpose of my code is to take in input of what something costs and how much was paid. the output would be the difference and the resulting dollars and coins that must be returned. here is the code i'm having difficulty with.

package another;

import javax.swing.JOptionPane;

/**
 *
 * @author Will
 */
public class Another {

    public static void tryAgain() {
        JOptionPane.showMessageDialog(null, "Enter a valid amount and try again");
        System.exit(0);
    }

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {

        String purchase = JOptionPane.showInputDialog("Please enter a the purchase amount");

        if (purchase == null) {
            System.exit(0);
        }

        if (purchase.isEmpty()) {
            tryAgain();
        }

        for (int i = 0; i < purchase.length(); i = i + 1) {
            if (!Character.isDigit(purchase.charAt(i))
                    && !purchase.contains(".")) {
                tryAgain();
            }
        }

        String given = JOptionPane.showInputDialog("Please enter the given amount");

        if (given == null) {
            System.exit(0);
        }

        if (given.isEmpty()) {
            tryAgain();
        }

        for (int i = 0; i < given.length(); i = i + 1) {
            if (!Character.isDigit(given.charAt(i))
                    && !given.contains(".")) {
                tryAgain();
            }
        }

        Double a = Double.parseDouble(purchase);
        Double b = Double.parseDouble(given);
        Double c = b - a;

        if (c < 0) {
            JOptionPane.showMessageDialog(null, "Give the cashier more money!");
            System.exit(0);
        }

        System.out.println( "Change: $" + c);

        if (c > 100) {
            double hundredsPlusExtra = c / 100;
            double hundredsWithout = Math.floor(hundredsPlusExtra); //this line rounds down
            c = c - hundredsWithout * 100;
            if (hundredsWithout == 1) {
                System.out.println(hundredsWithout + " One-Hundred Dollar Bill");
            } else {
                System.out.println(hundredsWithout + " Hundred Dollar Bills");
            }
        }

        if (c > 50) {
            double fiftiesPlusExtra = c / 50;
            double fiftiesWithout = Math.floor(fiftiesPlusExtra); //this line rounds down
            c = c - fiftiesWithout * 50;
            if (fiftiesWithout == 1) {
                System.out.println(fiftiesWithout + " Fifty Dollar Bill");
            } else {
                System.out.println(fiftiesWithout + " Fifty Dollar Bills");
            }
        }

        if (c > 20) {
            double twentiesPlusExtra = c / 20;
            double twentiesWithout = Math.floor(twentiesPlusExtra); //this line rounds down
            c = c - twentiesWithout * 20;
            if (twentiesWithout == 1) {
                System.out.println(twentiesWithout + " Twenty Dollar Bill");
            } else {
                System.out.println(twentiesWithout + " Twenty Dollar Bills");
            }
        }

        if (c > 10) {
            double tensPlusExtra = c / 10;
            double tensWithout = Math.floor(tensPlusExtra); //this line rounds down
            c = c - tensWithout * 10;
            if (tensWithout == 1) {
                System.out.println(tensWithout + " Ten Dollar Bill");
            } else {
                System.out.println(tensWithout + " Ten Dollar Bills");
            }

        }

        if (c > 5) {
            double fivesPlusExtra = c / 5;
            double fivesWithout = Math.floor(fivesPlusExtra); //this line rounds down
            c = c - fivesWithout * 5;
            if (fivesWithout == 1) {
                System.out.println(fivesWithout + " Five Dollar Bill");
            } else {
                System.out.println(fivesWithout + " Five Dollar Bills");
            }

        }

        if (c > 1) {
            double onesPlusExtra = c / 1;
            double onesWithout = Math.floor(onesPlusExtra); //this line rounds down
            c = c - onesWithout * 1;
            if (onesWithout == 1) {
                System.out.println(onesWithout + " One Dollar Bill");
            } else {
                System.out.println(onesWithout + " One Dollar Bills");
            }
        }

        if (c > .25) {
            double quartersPlusExtra = c / .25;
            double quartersWithout = Math.floor(quartersPlusExtra); //this line rounds down
            c = c - quartersWithout * .25;
            if (quartersWithout == 1) {
                System.out.println(quartersWithout + " Quarter");
            } else {
                System.out.println(quartersWithout + " Quarters");
            }
        }
    }
}
WonderWorld
  • 956
  • 1
  • 8
  • 18
  • How do you represent decimal numbers in binary? – Sotirios Delimanolis Jan 26 '14 at 03:48
  • The only integers I see in your code are the `for` loop indices and the integer literals. – Sotirios Delimanolis Jan 26 '14 at 03:49
  • 2
    [What Every Computer Scientist Should Know About Floating Point](http://docs.oracle.com/cd/E19957-01/806-3568/ncg_goldberg.html) – Don Roby Jan 26 '14 at 03:52
  • @SotiriosDelimanolis you should know integers never look like 9.999999999999998, so he must mean double. :) – WonderWorld Jan 26 '14 at 03:55
  • 2
    To the down-voters, please try searching for answers on this topic before down-voting. It is (unfortunately) not easy to find relevant answers to this question, based on keywords in the question. – Andrew Thompson Jan 26 '14 at 04:13
  • 2
    I agree with @AndrewThompson. I mark these questions as duplicates whenever I get to one before it has been closed, but I don't downvote. The relationship to previous questions is glaringly obvious to those who are already aware of floating point rounding error as a general phenomenon. They look like unique, weird situations to those who don't know about rounding error. – Patricia Shanahan Jan 26 '14 at 18:20

2 Answers2

2

You're doing your calculations using double.

Please take a look on this http://floating-point-gui.de/

Also http://www.mkyong.com/java/how-do-calculate-monetary-values-in-java-double-vs-bigdecimal/

Leo
  • 6,480
  • 4
  • 37
  • 52
1

I admit, I didn't read your code, but I'm 99% sure that you're having a problem with binary datastorage.

You see, in the decimal system, 1/10 can be easily represented as 0.1. However, try 1/3, it becomes 0.33333333333333333...

In binary, 1/10 is 0.0001100110011001100110011...

Look into BigDecimal for base10 numberstorage.

Reinstate Monica
  • 2,767
  • 3
  • 31
  • 40