Middle
Могат ли да се използват числа с плаваща запетая като ключове на контейнери?
sobes.tech AI
Отговор от AI
Не се препоръчва.
Причини:
- Проблеми с сравняването: Числата с плаваща запетая не винаги могат да бъдат точно представени в двоичен формат. Сравнението за точно равенство
a == bможе да даде фалшив резултат поради грешки в представянето. Контейнерите, базирани на дървета (като асоциативни масиви, множества) и хеш таблиците, разчитат на точно сравнение или на изчисление на хеш въз основа на точна стойност. - Нестабилност на хеша: Стойността на хеша на число с плаваща запетая, изчислена въз основа на неговото двоично представяне, няма да бъде стабилна при малки промени в стойността. Близки по стойност числа могат да имат много различни хешове, а еднакви по стойност числа (получени чрез различни изчисления поради грешки) могат да имат различни хешове. Това намалява ефективността на хеш таблиците (например
std::unordered_map). - Поведение на
NaNиInfinity: Специалните стойности (NaN,Infinity) имат неопределено или нестандартизирано поведение при сравнение и хеширане, което може да доведе до непредсказуеми резултати.
Вместо това може да се използва:
- Целочислено представяне, ако е приложимо (например, съхраняване на стойности в стотни).
- Специализирани класове за сравнение или хеширане с вземане предвид на допустима грешка (epsilon), но това усложнява използването на стандартните контейнери.
boost::float_column, ако се използва библиотеката Boost.
Пример за проблем с сравняването:
#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; // Може да не се покаже
} else {
std::cout << "0.1 + 0.2 != 0.3 (заради грешка в точността)" << std::endl;
}
return 0;
}