Naman
Naman

Reputation: 2669

Java double addition rounding off

In java following expression results into

new Double(1.0E22) + new Double(3.0E22)  = 4.0E22

but

new Double(1.0E22) + new Double(4.0E22)  = 4.9999999999999996E22

I was expecting it to be 5.0E22. The Double limit is 1.7976931348623157E308. Appreciate your help. My machine's architecture is x64 and JVM is also 64 bit.

Upvotes: 1

Views: 776

Answers (2)

Zim-Zam O'Pootertoot
Zim-Zam O'Pootertoot

Reputation: 18148

There are a few ways that you can reduce floating point errors, e.g. pairwise summation and Kahan summation, but neither of these will help you precisely represent a number like 5.0E22 - as Stefano Sanfilippo stated in his answer, that's due to the limits of what you can represent in using floating point, as opposed to a problem with the algorithm used to achieve the answer. To represent 5.0E22 you should either use BigDecimal or else use a library that has a Rational data type, e.g. JScience.

Upvotes: 0

Stefano Sanfilippo
Stefano Sanfilippo

Reputation: 33056

Welcome to the planet of floating point units. Unfortunately, in a real world, you have to give up some precision to get speed and breadth of representation. You cannot avoid that: double is only an approximate representation. Actually, you cannot represent a number but with finite precision. Still, it's a good approximation: less than 0.00000000001% error. This has nothing to do with double upper limits, rather with CPU limits, try doing some more math with Python:

>>> 4.9999999999999996 / 5.
1.0
>>> 5. - 4.9999999999999996
0.0

See? As a side note, never check for equality on double, use approximate equality:

if ((a - b) < EPSILON)

Where EPSILON is a very small value. Probably Java library has something more appropriate, but you get the idea.

If you are insterested in some theory, the standard for floating point operations is IEEE754

Upvotes: 4

Related Questions