Win a copy of Java EE 8 High Performance this week in the Java/Jakarta EE forum!
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
Sheriffs:
Saloon Keepers:
Bartenders:

Ranch Hand
Posts: 108
Hello,
I'm trying to add to Doble numbers with 2 decimal places, 12,25 + 23, 46 = 35, 71
I get most of the time.
But some times, for example, 12,10 + 20,15 gets 32,24999999999999999999996
Why?

Sheriff
Posts: 21208
87
Because floating point numbers are not precise enough, in the same sense that 1/3 is not precise enough when written in decimals. Check out http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems

The simple solution is to use ints representing the numbers times 100 (can be useful when dealing with adding / subtracting simple money values; the ints then represent the cents), or more intuitively use BigDecimal.

Greenhorn
Posts: 19

Fernando Dominguez wrote:Hello,
I'm trying to add to Doble numbers with 2 decimal places, 12,25 + 23, 46 = 35, 71
I get most of the time.
But some times, for example, 12,10 + 20,15 gets 32,24999999999999999999996
Why?

I'm a student engineer, no java expert at all but I can tell you a bit about numerical math:

A simple sum like 12,10 + 20,15 that gets 32,24999999999999999999996 is impossible in my opinion.

Rounding errors like these can come however from for example:
Endless numbers like pi and 0.99999999...., they will only be saved to about 16 numbers exact (I think) and therefore have some rounding errors.
Doing multiple operations with such numbers can result increase these rounding errors.
Doing operations with really small numbers is also verry unstable.

It's not java's fault, it's just the way computers work with numbers. You have to search for a more "Numerical stable" algorithm.

Using the BigDecimal class for your operations can also solve the problem because you will then save your numbers to more places exact.

I hope this very short intro to numerical math answered a bit of your question.

Java Cowboy
Sheriff
Posts: 16080
88
Java's float and double data types are stored in IEEE 754 floating point format. Such floating-point number have a limited number of bits (32 bits for a float, 64 bits for a double) and therefore can't store numbers with arbitrary precision.

IEEE 754 floating point numbers are stored as binary fractions. Some numbers simply cannot be represented with a finite number of digits by a binary fraction, just like some numbers like 1/3 cannot be represented by a finite number of digits as a decimal fraction.

If you need arbitrary precision, use BigDecimal instead of float or double.

Rob Spoor
Sheriff
Posts: 21208
87
Karsten, you are mostly right, but if you read the Wiki article I linked to you will see that even numbers like 0.1 cannot be represented exactly on computers. Being binary, only 1/2 and multiples of it can be represented exactly, and the sum of them. So something like 0.625, which is 0.5 + 0.125 or 1/2 + 1/8, can be represented exactly, but just like many natural fractions cannot be represented perfectly in the decimal system (1/3, 2/7, etc), many decimal numbers cannot be represented perfectly in the binary system. With the example, 12.10 is as much an approximation in binary as 1/3 is in decimal, and therefore there will indeed be rounding errors.

And you are most definitely right that this is not Java's fault. The same will happen in almost every programming language, since the problem is caused by the underlying system.

 Fire me boy! Cool, soothing, shameless self promotion: The WEB SERVICES and JAX-RS Course https://coderanch.com/t/690789/WEB-SERVICES-JAX-RS