Junior
Kuidas kontrollida kahe ujukomaarvu (float) võrdust?
sobes.tech AI
Vastus AI-lt
Võrdlemine otse == operaatoriga ei ole soovitatav seetõttu, et arvutuste esitus ja ümardamine võivad põhjustada vigu. Selle asemel tuleks kontrollida, kas kahe numbri absoluutne erinevus on väikese künnise (epsilon) piires.
bool are_equal(float a, float b, float epsilon = 0.00001f) {
return std::abs(a - b) < epsilon;
}
Stabiilsem lähenemine arvestab suhtelise veaga, eriti kui võrreldavad arvud on väga suured või väga väikesed:
#include <cmath>
#include <limits>
bool are_equal_robust(float a, float b, float epsilon = std::numeric_limits<float>::epsilon()) {
// Võrdleme erinevust arvu mõõtmetega
// Oluline on eraldi käsitleda nulli ja lõpmatust
if (a == b) {
return true; // Käsitleb juhtumeid a=b (sh lõpmatus ja NaN, kui need on omavahel võrdsed – mis ei kehti NaN-i puhul, kuid kehtib lõpmatuse puhul)
}
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; // Mõlemad arvud on lähedased nullile
} else {
return absolute_difference / max_abs < epsilon; // Suhtelise erinevuse võrdlus
}
}
Epsilon valik sõltub nõutavast täpsusest ja võrreldavate väärtuste vahemikust. std::numeric_limits<float>::epsilon() esindab väikseimat arvu, mille puhul 1.0 + epsilon on erinev 1.0-st.
Oluline on meeles pidada, et NaN (Not a Number) võrdlus alati tagastab false, kaasa arvatud NaN võrdlus iseendaga (nan == nan on alati false). Kui on vaja NaN-i eraldi töödelda, tuleb see teha eraldi.