Sobes.tech
Junior

İki onluq ədədlərin (float) bərabərliyini necə yoxlamaq olar?

sobes.tech Süni İntellekt

AI-dan cavab

Birbaşa == operatoru ilə müqayisə etmək tövsiyə edilmir, çünki təqdimat və yuvarlama xüsusiyyətləri ilə əlaqədardır. Əvəzində, ədədlər arasındakı fərqin mütləq dəyərinin kiçik bir hədd (epsilon) daxilində olub-olmadığını yoxlamaq lazımdır.

bool are_equal(float a, float b, float epsilon = 0.00001f) {
    return std::abs(a - b) < epsilon;
}

Daha dayanıqlı yanaşma, xüsusən çox böyük və ya çox kiçik ədədlərin müqayisəsində nisbət xətasını nəzərə alır:

#include <cmath>
#include <limits>

bool are_equal_robust(float a, float b, float epsilon = std::numeric_limits<float>::epsilon()) {
    // ədədlərin miqyasını nəzərə alaraq fərqi müqayisə edir
    // Sıfır və sonsuzluq halları ilə ayrıca məşğul olmaq vacibdir
    if (a == b) {
        return true; // a=b halları üçün işləyir (sonsuzluq və NaN daxil olmaqla, əgər onlar bir-birinə bərabərdirsə – NaN üçün deyil, amma sonsuzluq üçün)
    }

    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; // Hər iki ədəd sıfıra yaxındır
    } else {
        return absolute_difference / max_abs < epsilon; // Nisbət fərqinin müqayisəsi
    }
}

epsilon seçimi, tələb olunan dəqiqlik və müqayisə edilən dəyərlərin diapazonundan asılıdır. std::numeric_limits<float>::epsilon() ən kiçik ədədi təmsil edir ki, 1.0 + epsilon 1.0-dən fərqlidir.

NaN (Number olmayan dəyər) ilə müqayisə həmişə false qaytarır, hətta nan == nan da. Əgər NaN ilə işləmək lazımdırsa, bu ayrıca həyata keçirilməlidir.