Назад к вопросам
Junior
110
questionbank

Как проверить равенство двух чисел с плавающей точкой (float)?

Sobes Copilot

Получайте ответы в реальном времени

Ответ от нейросети

sobes.tech AI

Сравнивать напрямую оператором == не рекомендуется из-за особенностей представления и округления. Вместо этого следует проверить, находится ли абсолютное значение разности чисел в пределах некоторого малого порога (эпсилон).

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 всегда false). Если требуется обрабатывать NaN, это должно делаться отдельно.