This week's book giveaways are in the Refactoring and Agile forums.We're giving away four copies each of Re-engineering Legacy Software and Docker in Action and have the authors on-line!See this thread and this one for details.
Win a copy of Re-engineering Legacy Software this week in the Refactoring forum
or Docker in Action in the Agile forum!

# Numerical methods using Java, Precision

Siamak Saarmann
Ranch Hand
Posts: 78
Hello,

I need to solve some partial differential equations using java (using finite difference). In past I used to ignore this problem with double precision in Java. but now I am caught.

I have variable t which I increase 0.1 each time for example. Now when I print t:

t=0.1
t=0.2
t=0.30000000000000004
t=0.4
t=0.5
t=0.6
t=0.7
t=0.7999999999999999
t=0.8999999999999999
t=0.9999999999999999
t=1.0999999999999999
...

Then I use the t in my calculations. In addition to the difference of above numbers to what I need for my calculations (which is small) these are not the numbers I need. I need to find the result for t=1.1 entry (by comparing t to 1.1 in an results array but there is no 1.1).

How can I deal with this? And generally how can I compare double variables (if it is possible at all).

Regards,
Mac

Campbell Ritchie
Sheriff
Posts: 48394
56
But you have 1.1. Only it looks like 1.099999999999.

This is an unavoidable problem with floating-point arithmetic (see this FAQ page and look for no 20). You can try the BigDecimal class, but beware; it takes umbrage if it gets a recurring division and you haven't specified precision and rounding mode. Or you will have to live with the imprecision!

And don't try using == with floating point numbers; you can go wildly astray, for the same reason.
You can't use == with BigDecimal; you have to use equals() or compareTo() == 0. The latter may be more useful.

Ranch Hand
Posts: 728
4
A way to sort of do == with floats is to define a close_enough value. For example:

float1 almost equals float2 if (abs(float1 - float2) < close_enough)

If you need exact equality, use an integer.

Siamak Saarmann
Ranch Hand
Posts: 78
Norm, I normally use this method, however I guess I will try Campbell's method also. I wish it is not much slower than literals.

Thank you very much.

Campbell Ritchie
Sheriff
Posts: 48394
56
I forgot; the BigInteger constructor is overloaded. Use the version which takes a String not a double:

new BigInteger("0.1") NOT new BigInteger(0.1).