-1

I am building a program that calculates the total cost of a restaurant bill. My program is rounding $18.135 down to $18.13. This is the code that I am using to round it to two decimal places:

tip = Math.round((charge * TIP_PERCENTAGE) * 100) / 100d;

All of the variables are doubles, and charge is equal to 100.75 and TIP_PERCENTAGE is equal to 0.18.

I tried a couple of things but I have not had any luck. I want the program to round $18.135 up to $18.14.

WeseltonDW
  • 23
  • 5
  • Are you sure it's 18.135? `(charge * TIP_PERCENTAGE) * 100` looks like plenty of floating point arithmetic that can lead to stuff like 18.134993578 or whatever. – Max Vollmer Aug 31 '18 at 14:22
  • 1
    That said, I recommend to use integer types for currencies, not floating point types. Makes everything much easier, as it avoids any errors due to floating point precision. When printing just print whatever/100 . whatever%100. – Max Vollmer Aug 31 '18 at 14:26
  • I punched the numbers into my calculator. Is there any way I could see what the program is doing behind the scenes? – WeseltonDW Aug 31 '18 at 14:26
  • 2
    Yes, use a debugger. – Max Vollmer Aug 31 '18 at 14:27
  • Either **charge** and **TIP_PERCENTAGE** must be float or double. What I did was the following: `float TIP_PERCENTAGE = 0.18f; float charge = 100.75f; System.out.println(Math.round((charge * TIP_PERCENTAGE) * 100) / 100d);` the result was: 18.14 – Alvaro Lemos Aug 31 '18 at 14:39
  • Alvaro, that worked. It turned out that since I was using doubles, something weird was happening with the math. I change all of the variables in my program into floats and now it is working perfectly. I changed the literals to 100f as well. My TI-83 agrees with the output. Thank you for your help. – WeseltonDW Aug 31 '18 at 14:56
  • Please be aware that switching from `double` to `float` doesn't actually resolve your problem. It is pure coincidence that you get a correct result with single precision, but that doesn't give you a guarantee that it works for every possible input. The same problem you had with double precision can still catch you with single precision. There was nothing "weird happening with the math". Read up on how floating point arithmetic works. – Max Vollmer Aug 31 '18 at 22:12
  • See this as well: https://stackoverflow.com/questions/588004/is-floating-point-math-broken – Max Vollmer Aug 31 '18 at 22:14

1 Answers1

-2

Try this

private static double round(double value, int places) {
   if (places < 0) throw new IllegalArgumentException();

   BigDecimal bd = new BigDecimal(Double.toString(value));
   bd = bd.setScale(places, RoundingMode.HALF_UP);
   return bd.doubleValue();
}

...

tip =(charge * TIP_PERCENTAGE) ;
tip = round(tip,2);
GiorgosDev
  • 1,757
  • 1
  • 14
  • 16
  • It is still 18.13. I am still pretty new to the Eclipse IDE, is there a way to use the debugging tools to see what the code is doing? – WeseltonDW Aug 31 '18 at 14:32
  • http://www.vogella.com/tutorials/EclipseDebugging/article.html – GiorgosDev Aug 31 '18 at 14:33
  • I figured out what was happening. I used this bit of code to see what the program was doing. System.out.println(charge * TIP_PERCENTAGE); It turns out the code is calculating this as 18.134999999999998, so it actually should round it down $18.13. – WeseltonDW Aug 31 '18 at 14:40