In Java, I have defined k as
double k=0.0;
I am taking data from database and adding the same using while
loop,
while(rst.
You're still going via double
. Stick to BigDecimal
everywhere:
BigDecimal k = BigDecimal.ZERO;
while (rst.next()) {
k = k.add(new BigDecimal(rst.getString(5));
}
Alternatively - and preferrably, if the field in the database is actually a decimal value:
BigDecimal k = BigDecimal.ZERO;
while (rst.next()) {
k = k.add(rst.getBigDecimal(5));
}
You need to have k
as BigDecimal
too, instead of double
.
Use BigDecimal.ROUND_HALF_UP (or .._DOWN or .._EVEN).
Floating point calculations are inherently inaccurate and the small errors accumulate. That's why your end result is off by a small amount. If you always round up, a small positive error like 1.0000000001 becomes 1.01.
Alternatively you can use BigDecimal also for the calculations. That way you won't have an error in the end result in the first place. Just remember to use the BigDecimal(String) constructor, or obtain the BigDecimal directly from the result set.
I assume rst
is a ResultSet. Make sure you are using getBigDecimal rather than Double.parseDouble(rst.getString(5))
:
BigDecimal k = BigDecimal.ZERO;
while(rst.next()) {
k = k.add(rst.getBigDecimal(5));
}
And first of all: why aren't you adding these numbers in the database directly using appropriate SQL SUM
query?
As to your second question, double
is a binary floating point number. This means that it is expressed as a sum of powers of two. Don't ever use those for calculating monetary values. (if that's what you're summing up there). BigDecimal uses decimal arithmetic, so this is more in line to what we use.
Numbers such as 0.1
are infinite fractions in binary, in this case: 0.000110011...
thus you cannot get a reliable and exact result from using double
.