Safe Floating-Point Comparisons

How do I handle floating-point comparisons when the numbers might not be exactly equal?

When working with floating-point numbers, direct comparisons using == can be problematic because of how computers represent decimal numbers. Let's look at why this happens and how to handle it properly.

The Problem

Here's an example that demonstrates why floating-point comparisons can be tricky:

#include <iostream>
using namespace std;

int main() {
  float x{0.1f + 0.2f};
  float y{0.3f};

  // This might print "false" even though
  // mathematically they're equal!
  cout << "Direct comparison (x == y): "
    << (x == y) << "\n";
  cout << "Value of x: " << x << "\n";
  cout << "Value of y: " << y;
}
Direct comparison (x == y): false
Value of x: 0.3
Value of y: 0.3

Even though both numbers print as 0.3, they might not be exactly equal internally due to how floating-point numbers are stored in memory.

The Solution: Compare with Tolerance

Instead of checking for exact equality, we should check if the numbers are "close enough" by defining an acceptable difference (often called epsilon or tolerance):

#include <iostream>
using namespace std;

int main() {
  float Health{100.0f};
  float MaxHealth{100.0f};
  float Damage{33.33f};

  // Apply damage
  Health = Health - Damage;

  // This is safer than using ==
  float Tolerance{0.0001f};
  bool areEqual{
    (Health - MaxHealth) < Tolerance &&
    (MaxHealth - Health) < Tolerance
  };

  cout << "Health: " << Health << "\n";
  cout << "Are equal?: " << areEqual << "\n";

  // For less/greater comparisons
  // we can still use < and >
  bool isHealthy{Health > 50.0f};
  cout << "Is healthy?: " << isHealthy;
}
Health: 66.67
Are equal?: false
Is healthy?: true

Note that < and > comparisons are generally safe with floating-point numbers. It's primarily the equality comparison that needs special handling.

The actual value you use for Tolerance depends on your specific needs - smaller values mean more precise comparisons but are more likely to fail due to floating-point imprecision.

Booleans - true and false values

An overview of the fundamental true or false data type, how we can create them, and how we can combine them.

Questions & Answers

Answers are generated by AI models and may not have been reviewed. Be mindful when running any code on your device.

Why Booleans Take a Byte of Memory
If booleans only store true/false, why do they take up a whole byte of memory?
Optimizing Boolean Logic
How can I optimize boolean expressions when I have many conditions to check?
Tracking Boolean State Changes
How do I handle situations where I need to track the history of boolean state changes?
Not Operator vs Equals False
When should I use ! versus == false when checking if a boolean is false?
Debugging Complex Boolean Logic
How do professional programmers debug complex boolean expressions?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant