Comparing Floating Point Numbers

How do I compare ranges that contain floating-point numbers?

Comparing ranges that contain floating-point numbers requires careful handling due to potential precision issues. Floating-point arithmetic can introduce small errors, making direct comparisons unreliable. Instead, it's best to use a tolerance-based comparison.

Using a Custom Comparison Function

You can create a custom comparison function that checks if the absolute difference between two floating-point numbers is within a specified tolerance.

Here's an example:

#include <algorithm>
#include <cmath>  // Needed for std::abs
#include <iostream>
#include <vector>

bool almostEqual(double a, double b) {
  return std::abs(a - b) < 0.0001;
}

int main() {
  std::vector<double> A{1.0, 2.000001, 3.0};
  std::vector<double> B{1.0, 2.0, 3.0};

  if (std::ranges::equal(A, B, almostEqual)) {
    std::cout << "Ranges are equal";
  } else {
    std::cout << "Ranges are not equal";
  }
}
Ranges are equal

In this example, almostEqual() compares the floating-point numbers within a tolerance of 0.0001, ensuring that small differences due to precision issues are ignored.

Comparing with std::ranges::mismatch()

You can also use std::ranges::mismatch() to find where two ranges of floating-point numbers differ:

#include <algorithm>
#include <cmath>  // Needed for std::abs
#include <iostream>
#include <vector>

bool almostEqual(double a, double b) {
  return std::abs(a - b) < 0.0001;
}

int main() {
  std::vector<double> A{1.0, 2.00001, 3.0};
  std::vector<double> B{1.0, 2.0, 3.1};

  auto [itA, itB] = std::ranges::mismatch(
    A, B, almostEqual);

  if (itA != A.end() && itB != B.end()) {
    std::cout << "First mismatch - A: " << *itA
      << ", B: " << *itB;
  } else {
    std::cout
      << "Ranges are equal within tolerance";
  }
}
First mismatch - A: 3, B: 3.1

Practical Considerations

  • Tolerance Level: Choose an appropriate tolerance level for your application. The value may need adjustment based on the precision of your data.
  • Performance: Custom comparison functions may introduce a small performance overhead, but they are essential for accurate floating-point comparisons.
  • Consistency: Ensure consistent use of the tolerance level across all comparisons to avoid discrepancies.

Comparing floating-point numbers accurately requires accounting for precision issues, and using a custom comparison function with a defined tolerance is the most reliable method.

Comparison Algorithms

An introduction to the eight main comparison algorithms in the C++ Standard Library

Questions & Answers

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

std::equal() vs std::is_permutation()
What is the difference between equal() and is_permutation()?
Custom Comparison for std::equal()
How do I customize the comparison behavior for equal()?
Handling Mismatch Results
How do I handle past-the-end iterators returned by mismatch()?
Equal vs Lexicographical Compare
When should I use lexicographical_compare() over equal()?
Applications of is_permutation()
What are some practical applications of is_permutation()?
Comparing Different Length Ranges
How do I compare two ranges of different lengths using mismatch()?
Understanding Identity Permutations
What are identity permutations and why are they important?
Or Ask your Own Question
Get an immediate answer to your specific question using our AI assistant