Как да проверите равенството на две числа с плаваща точка (float)?
sobes.tech AI
Отговор от AI
Не е препоръчително да се сравнява директно с оператора == поради особеностите на представянето и закръгляването. Вместо това трябва да се провери дали абсолютната стойност на разликата между числата е в рамките на малък праг (epsilon).
bool are_equal(float a, float b, float epsilon = 0.00001f) {
return std::abs(a - b) < epsilon;
}
По-устойчивият подход взема предвид относителната грешка, особено при сравняване на много големи или много малки числа:
#include <cmath>
#include <limits>
bool are_equal_robust(float a, float b, float epsilon = std::numeric_limits<float>::epsilon()) {
// Сравняваме разликата с оглед на мащаба на числата
// Важно е да се обработват отделно случаите с нула и безкрайност
if (a == b) {
return true; // Обработка на случаите a=b (включително инфинити и NaN, ако са равни – което не е вярно за NaN, но за инфинити е)
}
float absolute_difference = std::abs(a - b);
float max_abs = std::max(std::abs(a), std::abs(b));
if (max_abs < epsilon) {
return absolute_difference < epsilon; // И двата числа са близо до нула
} else {
return absolute_difference / max_abs < epsilon; // Сравнение на относителната разлика
}
}
Изборът на epsilon зависи от необходимата точност и диапазона на сравняваните стойности. std::numeric_limits<float>::epsilon() представлява най-малкото число, такова че 1.0 + epsilon се различава от 1.0.
Важно е да се помни, че сравняването с NaN (Not a Number) винаги връща false, включително nan == nan. Ако е необходимо да се обработват NaN стойности, това трябва да стане отделно.