programming forums Java Java JSRs Mobile Certification Databases Caching Books Engineering OS Languages Paradigms IDEs Build Tools Frameworks Products This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
Sheriffs:
Saloon Keepers:
Bartenders:

Double subtraction error

Rob Cromley
Greenhorn
Posts: 24
The users where I work found an interesting problem that I've been trying to figure-out. I've got a workaround coded and out to them but I'm still confused about how in the world there was a problem in the first place. The code below illustrates the problem. I start with variable dCheckAmt with a dollar amount of 7.79. It goes through calculations to multiply this amount by .72 then round to the nearest penny. When I get to the ***** in the code below the value for dCheckAmt is 7.79 and the value for dSide1Amt is 5.61. I would think that the subtraction should result in a value of 2.18. It doesn't. The value of dSide2Amt is 2.1799999999999997. As I change the original amount from 7.79 sometimes it comes out correctly and sometimes it doesn't. Any idea about how this is happening so I can sleep peacefully tonight?

public class CheckRounding {

public static void main(String[] args) {

double dCheckAmt = 7.79;
double dSide1Amt = dCheckAmt * .72;
double lTemp = Math.round((dSide1Amt * 100.0));
dSide1Amt = lTemp / 100.0;
// ***** At this point it looks OK
double dSide2Amt = dCheckAmt - dSide1Amt;

System.out.println("Check Amt=" + dCheckAmt);
System.out.println("Side1 Amt=" + dSide1Amt);
System.out.println("Side2 Amt=" + dSide2Amt);
}
}

This produces output:
Check Amt=7.79
Side1 Amt=5.61
Side2 Amt=2.1799999999999997

Stefan Krompass
Ranch Hand
Posts: 75
Hi,

the problem is that floating values are inherently imprecise. Consider using BigDecimal instead

Stefan

Peter Chase
Ranch Hand
Posts: 1970
As a general rule, one should not use floating-point (float or double) calculations for currency. One can either use BigDecimal, as suggested by another contributor, or integers. In the latter case, the integer calculations should be done in the smallest unit of the currency (cents, pence...). Only convert to dollars/pounds for print-out.