What's wrong with using == to compare floats in Java?
Using ==
to compare floating point numbers in Java is not reliable due to binary representation inaccuracies. Instead, the safer approach is to see if the difference between the two numbers is small enough or within a specific tolerance level.
Example:
Key takeaways:
- Precision issues might bite with binary floating-point
- Use tolerance or
EPSILON
to keep precision errors at bay Math.abs(a - b) < EPSILON
: Always have this pattern in mind- Context-awareness is key when deciding EPSILON's value
Pitfalls of ==
for float comparison
The ==
operator in Java checks for exact bit-by-bit equality, leading to misleading results when used with floating point numbers. The reason lies in the rounding errors and approximations inherent to binary representation. For instance, the decimal number 0.1
cannot be perfectly represented in binary. This results in false negatives when comparing the results of arithmetic operations using ==
.
Also, remember that the size of the epsilon value should be chosen judiciously based on the precision requirements of your specific task.
When epsilon is your best friend:
The epsilon value becomes a necessity in some special scenarios:
- When complex calculations are involved
- Working with geometric algorithms that can tolerate minor differences
- Validating simulation results in scientific computations
- Designing applications dealing with financial calculations where the difference of a cent matters but not that of a sub-cent fraction
There's not only one way to Rome:
Lest we forget, there are other respectable ways to compare floats:
- Have a taste of wrapper classes and use
equals()
for exact equality - Try
Float.compare()
orDouble.compare()
. They consider special cases such as NaN and infinity
Decimal vs Binary: a love-hate relationship
In their internal binary representation, floating points adopt scientific notation leading to approximative representations. Example: 0.1 + 0.2 != 0.3
due to such binary rounding.
Shadows of floating-point comparison
Implicit casting can be a culprit when comparing different data types. Another facet to consider is that machine epsilon might vary from system to system and algorithm to algorithm, complicating the equation.
Trading off precision for Performance
For critical systems, you might have to make a decision between precision and performance. The use of an epsilon might be an additional overhead but is amendable to fine-tuning catering to precision needs.
Was this article helpful?