Junior
Kā pārbaudīt divu peldošo punktu skaitļu (float) vienādību?
sobes.tech AI
Atbilde no AI
Tiešā salīdzināšana ar operatoru == nav ieteicama, ņemot vērā pārstāvības un noapaļošanas īpatnības. Tā vietā jāparbauda, vai abu skaitļu absolūtā atšķirība ir mazāka par nelielu slieksni (epsilon).
bool are_equal(float a, float b, float epsilon = 0.00001f) {
return std::abs(a - b) < epsilon;
}
Vairāk izturīgs pieejas ņem vērā relatīvo kļūdu, īpaši, salīdzinot ļoti lielus vai ļoti mazus skaitļus:
#include <cmath>
#include <limits>
bool are_equal_robust(float a, float b, float epsilon = std::numeric_limits<float>::epsilon()) {
// Salīdzina atšķirību, ņemot vērā skaitļu mērogu
// Ir svarīgi atsevišķi apstrādāt nulles un bezgalības gadījumus
if (a == b) {
return true; // Apstrādā gadījumus, kad a=b (ieskaitot bezgalību un NaN, ja tie ir vienādi – kas nav NaN gadījumā, bet ir bezgalība)
}
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; // Abi skaitļi ir tuvu nullei
} else {
return absolute_difference / max_abs < epsilon; // Relatīvās atšķirības salīdzinājums
}
}
epsilon izvēle ir atkarīga no nepieciešamās precizitātes un salīdzināmo vērtību diapazona. std::numeric_limits<float>::epsilon() apzīmē mazāko skaitli, kuram ir īpašība, ka 1.0 + epsilon atšķiras no 1.0.
Svarīgi atcerēties, ka NaN (Not a Number) salīdzinājums vienmēr atgriež false, ieskaitot nan == nan. Ja nepieciešams, NaN jāapstrādā atsevišķi.