Sobes.tech
Junior

Ике сызгыч нүкте санын (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 (Number эмес сан) менен салыштырганда, ал дайыма false болот, анын ичинде nan == nan. Эгер NaN иштетүү керек болсо, аны өзүнчө иштетүү керек.