Sobes.tech
Middle

Lze používat čísla s plovoucí desetinnou čárkou jako klíče kontejnerů?

sobes.tech AI

Odpověď od AI

Nedoporučuje se.

Důvody:

  1. Problémy s porovnáváním: Čísla s plovoucí desetinnou čárkou nem mohou být vždy přesně reprezentována v binárním tvaru. Porovnání na přesnou rovnost a == b může vést k nesprávným výsledkům kvůli chybám v reprezentaci. Kontroléry založené na stromech (například asociativní pole, množiny) a hash tabulky spoléhají na přesné porovnání nebo výpočet hashe na základě přesné hodnoty.
  2. Nestabilita hashe: Hash hodnoty čísla s plovoucí desetinnou čárkou, vypočtená na základě jeho binárního zobrazení, nebude stabilní při malých změnách hodnoty. Blízká čísla mohou mít velmi odlišné hashe, a stejná čísla (získaná různými výpočty kvůli chybám) mohou mít odlišné hashe. To snižuje efektivitu hash tabulek (například std::unordered_map).
  3. Chování NaN a Infinity: Speciální hodnoty (NaN, Infinity) mají neurčité nebo nestandardní chování při porovnávání a hashování, což může vést k nepředvídatelným výsledkům.

Místo toho lze použít:

  • Celistvé reprezentace, pokud je to vhodné (například ukládání hodnot v setinách).
  • Specializované třídy pro porovnávání nebo hashování s ohledem na přípustnou odchylku (epsilon), ale to komplikuje použití standardních kontejnerů.
  • boost::float_column, pokud je použita knihovna Boost.

Příklad problému s porovnáváním:

#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; // Může se nezobrazit
    } else {
        std::cout << "0.1 + 0.2 != 0.3 (kvůli chybě přesnosti)" << std::endl;
    }
    return 0;
}