0

Ok, JavaSE 1.8 running an application in Eclipse Version: Oxygen.3a Release (4.7.3a) Build id: 20180405-1200. Simple arithmetic:

Double dblBalance; ( showing as 2072.41 in debug, but also running the app in the IDE)

Double dblAmountofAllocation; ( showing as 1900.0 at runtime )

dblBalance = dblBalance - dblAmountofAllocation; ( dblBalance shows 172.40999995 at runtime)
( my workaround - shouldn't be necessary)
dblBalance = Math.round(dblBalance * 100.0) / 100.0;

I have also tested this in a test case compiled and run from the command line. So it is reproducible. Is it the Java runtime engine?

very puzzled - I would like to know if this can be replicated by others. Most combinations of Double values don't have this problem - do I need to stick with the native data types?

MakePeaceGreatAgain
  • 35,491
  • 6
  • 60
  • 111
  • You forgot to mention your input-data and what you expect. I suppose you´re struggling about `double` - as well as any other floating-point number - isn´t accurate. – MakePeaceGreatAgain Jan 18 '20 at 21:39
  • Ok, I tried the native double data type and same error. – Harold Rosenkrans Jan 18 '20 at 21:39
  • I apologize Double dblBalance = 2072.41; Double AmountofAllocation = 1900.0; – Harold Rosenkrans Jan 18 '20 at 21:41
  • Indeed what you name "workaround" is exactly what you should do when dealing with floating-points. – MakePeaceGreatAgain Jan 18 '20 at 21:44
  • Yes, the struggle over accurate representation of decimal values. Is there a specific data type in Java like currency or decimal that takes care of all the messiness? – Harold Rosenkrans Jan 18 '20 at 21:44
  • You can use `BigDecimal`. – Kayaman Jan 18 '20 at 21:44
  • BigDecimal - thanks, I'll give it a try – Harold Rosenkrans Jan 18 '20 at 21:45
  • LOL BigDecimal dblBalance = new BigDecimal(2072.41); BigDecimal dblAmountofAllocation = new BigDecimal(1900.0); dblBalance = dblBalance.subtract(dblAmountofAllocation); System.out.println("Result is " + dblBalance.toPlainString()); the output is Result is 172.40999999999985448084771633148193359375 - I guess I just have to live with the workaround. Thanks for indulging me guys. I am consternated everytime I rediscover this simple fact of computing – Harold Rosenkrans Jan 18 '20 at 21:55
  • You're creating your BigDecimal wrong. Should be `BigDecimal.valueOf(2072.41)`, not `new BigDecimal(2072.41)`. Read the javadoc on constructor you're using. – M. Prokhorov Jan 18 '20 at 22:06
  • @HimBromBeere, `double` computations are accurate - but not all decimal numbers can be represented as floating point value with finite precision. – M. Prokhorov Jan 18 '20 at 22:10
  • 1
    Use BigDecimal("2072.41") If you convert the string "2072.41" to double at any point, you introduce rounding error. – Patricia Shanahan Jan 18 '20 at 22:14
  • Never ever use float/double for currency amounts – C.B. Jan 18 '20 at 23:22
  • Actually since this is an accounting App I think I will create a Currency class. I wish Java had adopted a little more of C and allowed operator definitions. Thanks for the tip on BigDecimal. I read the Oracle documentation but didn't really chew on it long enough – Harold Rosenkrans Jan 19 '20 at 22:47

0 Answers0