Sobes.tech
Junior

Ako skontrolovať rovnosť dvoch čísel s pohyblivou desatinnou čiarkou (float)?

sobes.tech AI

Odpoveď od AI

Direktno poređenje operatorom == se ne preporučuje zbog svojstava prikaza i zaokruživanja. Umesto тога, треба проверити да ли је апсолутна вредност разлике између бројева унутар мале границе (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 треба посебно обрадити.