Subhash Nambiar

Greenhorn

Posts: 26

posted 14 years ago

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.

Thanks in advance

Subhash

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.

Thanks in advance

Subhash

David Patterson

Ranch Hand

Posts: 65

posted 14 years ago

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

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

Cindy Glass

"The Hood"

Sheriff

Sheriff

Posts: 8521

posted 14 years ago

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 ]

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 ]

"JavaRanch, where the deer and the Certified play" - David O'Meara

Jim Yingst

Wanderer

Sheriff

Sheriff

Posts: 18671

posted 14 years ago

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

(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

[ January 06, 2003: Message edited by: Jim Yingst ]

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 ]

"I'm not back." - Bill Harding, *Twister*

It is sorta covered in the JavaRanch Style Guide. |