Win a copy of Functional Reactive Programming this week in the Other Languages forum!

# Behaviour of Add (+) Operator

Subhash Nambiar
Greenhorn
Posts: 26
Hi All
I was just wandering by a very abnormal output from the simple summation of double values in JAVA
Like i tried these examples
double d1 = .11;
double d2 = 1.53;
//Result : 1.6400000000000001
double d1 = .11f; //same value with f appended
double d2 = 1.53f; //same value with f appended
//Result : 1.639999970793724
double d1 = .11;
double d2 = 1.43;
//Result : 1.54
Though 1st one is almost correct but still not accurate and i couldnt able to trace the reason for this behaviour.And there is no fix pattern it is following.
Could anyone suggest what cld be the problem and where i shld look for finding the possible reason for it.
If i want to know how/which algorithm java do for (+) operator, where cld i find the same.
Subhash

David Patterson
Ranch Hand
Posts: 65
I think the problem is more in conversion of decimal fractions to binary fractions. There are errors introduced when you try to change 0 + 1/10 + 1/100 to something like
0 + 0/2 + 0/4 + 0/8 + n/16 + m/32 ...
The error is inescapable in binary arithmetic. The addition operator seems to be doing its job well. By the way, you could also see similar apparent errors with -, /, or * as well.
Dave Patterson
patterd1@comcast.net

Subhash Nambiar
Greenhorn
Posts: 26
That could be the possible reason but then is it be Platform dependent or this behaviour will be fix for any PC or platform.
Tegards
Subhash

Cindy Glass
"The Hood"
Sheriff
Posts: 8521
You can get imprecision when doing math with doubles in any language including C++, Cobol, Visual Basic etc. By it's very nature a double or a float would need to have an infinite number of decimal places to be exactly precise. Since that can never happen, all results in doubles are approximations at some point.
You need to decide what you level of precision is going to be needed. If you want to INSURE accuracy out to 4 decimal places, then Multiply both of the operands by 10,000 into integers, do the addition on the integers and then divide the result by 10,000. That gives you SOME control over the way that the precision is handled.
[ January 06, 2003: Message edited by: Cindy Glass ]

Jim Yingst
Wanderer
Sheriff
Posts: 18671
The exact output may vary slightly from platform to platform or JDK version to JDK version, but the basic problem is inherent to all Java implementations because of the way floating types are defined. If you want to guarantee that you see the exact same results on any platform/JDK, use the strictfp keyword. (Usually we don't really care about this, but it's available if you want it.)
There are four basic solutions to this problem:
(1) Ignore it. 1.6400000000000001 is so close to 1.64 that it really shouldn't matter in the real world. (However if you later do something like subtract 1.64 from the result, there may be a big different between 0 and 0.0000000000000001, so be careful.)
(2) Ignore it as above, except that whenever you need to display the result to an end user (who will be upset by the extra .0000000000000001) use a DecimalFormat object to round off the displayed result to some maximum number of digits.
(3) Use java.math.BigDecimal instead for float or double.

(4) Use integer types instead. For example if .11 and 1.53 represent prices in dollars and cents, then you may know that all prices will be in an integer number of cents - so do all your calcs in cents, using 11 and 153 rather than .11 and 1.53. To display final answers you may need to devide by 100.0 - this should be OK if it's the last thing you do.
[ January 06, 2003: Message edited by: Jim Yingst ]