2
$\begingroup$

I've found that 0.1 + 0.2 == 0.3 is not true in Java (see this demo).

So, I'm interested in how equality testing can be implemented for floats. Is there a standardized algorithm?

$\endgroup$
  • $\begingroup$ The best way I think is to compare them as follows $|f_1 - f_2| < \epsilon$, where $f_1$ and $f_2$ are floats and $\epsilon$ is small enought value. For example, you could set $\epsilon = 10^{-6}$ $\endgroup$ – 0xdeadcode Dec 31 '14 at 10:18
  • $\begingroup$ @Tautochrone That's not always good. It tells you that 0.0000007 is equal to 0.0000000000007, which is odd considering that one is a million times larger than the other. $\endgroup$ – Gilles Dec 31 '14 at 10:53
  • $\begingroup$ You are right @Gilles. I guess then whether it is good approach or not depends on the context. $\endgroup$ – 0xdeadcode Jan 2 '15 at 9:21
7
$\begingroup$

You cannot meaningfully test floating point values for equality. A floating point value does not represent a real number, it represents a range of real numbers, but it fails to store the width of this interval. All you can do with floating point values is to test them for approximate equality, and it's up to you to define the approximation you're willing to make. You can test whether the difference is smaller than a certain constant ($|x-y| \le \epsilon$), or whether it's relatively small ($|x-y| \le \epsilon \min\{x,y\}$), or something else; the right method and the value of $\epsilon$ depend on the calculation.

There is a seminal article on this topic: the aptly titled What Every Computer Scientist Should Know About Floating Point Arithmetic by David Goldberg [PDF]. Sure, it's long — that shows how difficult floating point is to use, if you care about things like whether 0.1 + 0.2 equals 0.3. And no, there is no magic bullet that would let you sweep the difficulties under the carpet. There is a good, more accessible summary called What Every Programmer Should Know About Floating-Point Arithmetic*, or, Why don’t my numbers add up?

Applications that require exact computations, such as financial computations, do not use floating point. They use integer or fixed-point arithmetic.

Applications that use floating point require a careful, expensive analysis to find out what the uncertainty in the result is. Keep in mind that a floating point value does not really represent a real number $m \cdot 2^e$ nor even a specific interval like $\left[(m-\frac12) 2^e, (m+\frac12) 2^e\right]$, but an interval whose width increases as the computation becomes longer as the uncertainty accumulates.

There is a standard for floating point operations, which most (but not all) systems today implement: IEEE 754 (“IEEE floating point”). This standard defines storage formats, rouding rules, denormalized numbers, etc. It tries to arrange for typical computations to be as precise as possible. Arranging for 0.1 + 0.2 to equal 0.3 is beyond its abilities (that would be possible, but then it would cause 0.2 + 0.3 not to equal 0.5 or some similar misfit).

Some threads on Stack Overflow on this topic:

$\endgroup$
5
$\begingroup$

The == operator invoke a float point compare instruction, this considers two numbers equal if neither is NaN, and they are exactly the same, or if they are positive and negative zero. Notably Infinity == Infinity, despite the mathematical dubiety of considering infinities equal, and Infinity - Infinity returning NaN.

So if the numbers are not exactly equal, for instance because of the inability of IEEE 754 floating point numbers to represent fractions where the denominator is not a power of $2$ exactly, the result will be that the numbers are considered unequal.

Note however that IEEE 754 floating point numbers are capable of representing all integers from $-2^{53}$ to $2^{53}$ exactly, which means that the equality operator can be used reliably with these numbers. This is pretty important in JavaScript (and any other language without integers), as it makes it easy to use floating point numbers in place of integers.

$\endgroup$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.