Sobes.tech
Middle

Can floating-point numbers be used as container keys?

sobes.tech AI

Answer from AI

Not recommended.

Reasons:

  1. Comparison issues: Floating-point numbers cannot always be represented exactly in binary form. Comparing for exact equality a == b can yield false results due to representation inaccuracies. Tree-based containers (associative arrays, sets) and hash tables rely on exact comparison or hash computation based on exact values.
  2. Hash instability: The hash value of a floating-point number, computed based on its binary representation, will not be stable against small changes in value. Numbers close in value may have very different hashes, and numbers with the same value (obtained through different calculations due to inaccuracies) may have different hashes. This leads to low efficiency of hash tables (e.g., std::unordered_map).
  3. Behavior of NaN and Infinity: Special values (NaN, Infinity) have undefined or non-standard behavior during comparison and hashing, which can lead to unpredictable results.

Instead, you can use:

  • Integer representation, if applicable (e.g., storing values in hundredths).
  • Specialized classes for comparison or hashing considering an acceptable margin of error (epsilon), though this complicates using standard containers.
  • boost::float_column, if using the Boost library.

Example of comparison problem:

#include <iostream>

int main() {
    double a = 0.1 + 0.2;
    double b = 0.3;
    if (a == b) {
        std::cout << "0.1 + 0.2 == 0.3" << std::endl; // Might not be printed
    } else {
        std::cout << "0.1 + 0.2 != 0.3 (due to inaccuracy)" << std::endl;
    }
    return 0;
}