1

I am wondering why I am losing precision when using this code :

double x = 12.0456;    // or float : same result
System.out.println(x); // outputs 12.0456 obviously
x %= 1;                // should now be equal to 0.0456 right?
System.out.println(x); // outputs 0.04560000000000031 or 0.045599937 when using float

12.0456 modulo 1 should equal 0.0456 right? But it shows a slightly different value, why do I keep losing precision? I mean the code should substract exactly 1 until the value is less than 1.

However, I found out a way to get the correct value :

double x = 12.0456;
System.out.println(x);
x %= 1;
System.out.println((float)x); //outputs 0.0456 exactly

This way works perfectly, but do you guys have a better solution?

I don't care which floating point type I should use, I just want to find a clean way to get the correct value! I don't like having to convert the value to a double and then to a float.

dominicbri7
  • 2,479
  • 4
  • 23
  • 33
  • 8
    You need to read up on the use of floating point numbers in Java. Your result is both expected and correct. – BeRecursive Feb 09 '13 at 22:23
  • Doubles are, in practice, only precise up to 6 to 8 significant figures. – Code-Apprentice Feb 09 '13 at 22:27
  • BeRecursive, do you know a method to get the result I want while being expected and correct? – dominicbri7 Feb 09 '13 at 22:27
  • @dominicbri7 `float`s and `double`s simply can't represent any arbitrary real number. If you need to maintain a known precision, use `BigDecimals`, but even those are only arbitrary-precision, not infinite-precision. (This might not be practically important.) – millimoose Feb 09 '13 at 22:49
  • @Code-Guru Doubles are 'in practice' accurate to 14-15 decimal digits: less so if there are fractions, and in a way that can't be reduced to just a simple number of decimal places. It depends on the actual value. – user207421 Feb 10 '13 at 11:20

1 Answers1

2

Float and double are imprecise - they have a finite amount of bits to represent a value.

Because humans use base 10, and computers use base 2, numbers that appear "simple" to us can be impossible to represent accurately as a float/double, especially the results of computations due to way CPUs execute them.

Bohemian
  • 412,405
  • 93
  • 575
  • 722
  • To add to your answer, take the fraction `1/3` as an example. It is impossible to represent this precisely with a finite number of decimal places. Similar issues arise with binary representations of floating point numbers. – Code-Apprentice Feb 10 '13 at 20:08