1

I have encountered a rather unusual scenario in my coding. I have developed this app and it has been utilised for the past 6 months with no errors.

To simplify my problem.. I am using a decimalFormat to round up numbers and ensure that they are to 2 decimal places and this has been working perfectly.

However, a problem came up that was sent back to me and it was said that every other case works except for this specific one and it seems to be in particular just the number 4?

Case:

Total = 44.75 Mean = 4.475 MBW (2 decimal places) = 4.47 NOT 4.48

This led me to wonder is DecimalFormat always correct when rounding? the weird thing is this works when it is 1.475 it rounds to .48 and every number except for 4??

Anyone any ideas?

Java example:

 final DecimalFormat df = new DecimalFormat("#0.00");
 weight2 = 4.475
 MBW = df.format(weight2);

The result above is still getting 4.47.. any normal rounding should be 4.48? This is working for any other whole number such as 1.475 is 1.48, 2.275 is 2.48... why is the whole number 4 not working???

Rajeey3
  • 67
  • 10
  • Yes, please post code. I find it hard to believe that 1.475 works but not 4.475. – jingx Jan 16 '18 at 17:53
  • @jingx I have added the majority of the class as I am not sure what you need... it may be hard to understand but basically theres like inputs then a total is calc then the mean then the mean should be rounded to 2 decimal places and properly rounded. I hope you can see something I cant! – Rajeey3 Jan 16 '18 at 18:10
  • Are you able to reduce this to one line of code, like `df.format(4.475)` would output `4.47`, but `df.format(1.475)` would output `1.48`? Not trying to give you a hard time, but it's an effective way of both troubleshooting and posting for help, since if the behavior is lost during your reduction, then the problem is not in `DecimalFormat`. – jingx Jan 16 '18 at 18:52
  • the problem seems to be the whole number 4 which is very strange @jingx – Rajeey3 Jan 17 '18 at 08:49
  • @Henry I don't see how this is a duplicate??? – Rajeey3 Jan 17 '18 at 11:39
  • @Henry sorry I was asked to post code by the user above.. I have updated my code and problem. any ideas? this is a frustrating problem – Rajeey3 Jan 17 '18 at 15:18
  • I made a wrong assumption, the numbers are not exactly representable as a double. So turns out, it is a duplicate as I first thought. – Henry Jan 17 '18 at 15:26
  • Cannot close any longer as I have done that already. Possible duplicate of https://stackoverflow.com/questions/588004/is-floating-point-math-broken?noredirect=1&lq=1 – Henry Jan 17 '18 at 15:27
  • @Henry that is in no way a duplicate. it is not even relevant to my question. My question is about rounding that is about floating point numbers and addtions????????????? – Rajeey3 Jan 17 '18 at 15:29

1 Answers1

0

These numbers cannot be represented exactly as a double. Looking at the bit pattern of the numbers represented as a double:

1.475 -> 3ff799999999999a
4.475 -> 4011e66666666666

you see that the first is slightly larger than the exact value, while the other is slightly smaller than the exact value. So it is rounded down to 4.47.

You can also try the following experiment:

System.out.println(1.475 - 1);
System.out.println(4.475 - 4);
System.out.println(5.475 - 5);

The result is

0.4750000000000001
0.47499999999999964
0.47499999999999964
Henry
  • 42,982
  • 7
  • 68
  • 84
  • so how can I ensure that it does round to 4.48? or is this a loophole – Rajeey3 Jan 17 '18 at 15:31
  • You cannot. This is how floating point arithmetic works. Read the material linked in the duplicate question to get some insight. – Henry Jan 17 '18 at 15:52
  • ah right.. why is it just the number 4 in particular then? is this the only case where thebit pattern is greater than the number – Rajeey3 Jan 17 '18 at 16:23
  • no, the same happens for 5.475, 6.475, and many other numbers. – Henry Jan 17 '18 at 16:24
  • I can confirm this doesn't as I get .48 for all other results and have tested every one thoroughly. – Rajeey3 Jan 17 '18 at 16:26