Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to avoid floating point precision errors with floats or doubles in Java?

I have a very annoying problem with long sums of floats or doubles in Java. Basically the idea is that if I execute:

for ( float value = 0.0f; value < 1.0f; value += 0.1f )     System.out.println( value ); 

What I get is:

0.0 0.1 0.2 0.3 0.4 0.5 0.6 0.70000005 0.8000001 0.9000001 

I understand that there is an accumulation of the floating precision error, however, how to get rid of this? I tried using doubles to half the error, but the result is still the same.

Any ideas?

like image 264
tunnuz Avatar asked Mar 10 '11 08:03

tunnuz


People also ask

How do you get rid of floating-point errors?

Floating-point error mitigation is the minimization of errors caused by the fact that real numbers cannot, in general, be accurately represented in a fixed space. By definition, floating-point error cannot be eliminated, and, at best, can only be managed.

Which is more precise float or double Java?

Though both float and double datatype are used to represent floating-point numbers in Java, a double data type is more precise than float. A double variable can provide precision up to 15 to 16 decimal points as compared to float precision of 6 to 7 decimal digits.

Are doubles or floats more precise?

double has 2x more precision than float. float is a 32-bit IEEE 754 single precision Floating Point Number – 1 bit for the sign, 8 bits for the exponent, and 23* for the value. float has 7 decimal digits of precision.


1 Answers

There is a no exact representation of 0.1 as a float or double. Because of this representation error the results are slightly different from what you expected.

A couple of approaches you can use:

  • When using the double type, only display as many digits as you need. When checking for equality allow for a small tolerance either way.
  • Alternatively use a type that allows you to store the numbers you are trying to represent exactly, for example BigDecimal can represent 0.1 exactly.

Example code for BigDecimal:

BigDecimal step = new BigDecimal("0.1"); for (BigDecimal value = BigDecimal.ZERO;      value.compareTo(BigDecimal.ONE) < 0;      value = value.add(step)) {     System.out.println(value); } 

See it online: ideone

like image 182
Mark Byers Avatar answered Oct 12 '22 22:10

Mark Byers