Подтвердить что ты не робот

Отрицательная бесконечность

Я пытаюсь понять, как назначить значение отрицательной бесконечности для переменной float или double. Кажется, что, включая стандартные пределы библиотеки, я могу получить представление бесконечности, и я знаю (совершенно верно), что добавление минуса перед этим (-infinity) может привести к тому, что значение, которое я ищу в плавающей точке IEEE754 (как 0x7FFFFFFF может привести к 0xFFFFFFFF), но я даже не уверен в этом, не говоря уже о других стандартах, которые могут быть там (если они есть). Я нахожу это действительно, действительно непрофессиональным и зависимым от реализации.

Есть ли хороший способ получить ценность платформы и реализации отрицательной бесконечности независимо, конечно, иначе я мог бы просто использовать #define, всем нравится препроцессинг.

4b9b3361

Ответ 1

По крайней мере, если std:: numeric_limits:: is_iec559 (IEEE 754) истинно (что гарантирует, что std:: numeric_limits:: has_infinity также можно выразить положительные и отрицательные значения бесконечности так, как вы уже заявили.

Краткое описание значений бесконечности IEEE 754-1985 от Wikipedia:

...... надрез......

Поле смещенного экспоненты заполняется всеми 1 битом, чтобы указать либо бесконечность или неверный результат вычисления.

Положительная и отрицательная бесконечность

Положительная и отрицательная бесконечность представлены таким образом:

 sign = 0 for positive infinity, 1 for negative infinity.
 biased exponent = all 1 bits.
 fraction = all 0 bits.

...... надрез......

утверждения

Следующий пример будет работать так, как ожидалось, или вызвать ошибку времени компиляции в случае, если целевая платформа не поддерживает поплавки IEEE 754.

#include <cstdlib>
#include <cmath>
#include <cassert>
#include <limits>

int main(void)
{
    //Asserts floating point compatibility at compile time
    static_assert(std::numeric_limits<float>::is_iec559, "IEEE 754 required");

    //C99
    float negative_infinity1 = -INFINITY;
    float negative_infinity2 = -1 * INFINITY;

    float negative_infinity3 = -std::numeric_limits<float>::infinity();
    float negative_infinity4 = -1 * std::numeric_limits<float>::infinity();

    assert(std::isinf(negative_infinity1) && negative_infinity1 < std::numeric_limits<float>::lowest());
    assert(std::isinf(negative_infinity2) && negative_infinity2 < std::numeric_limits<float>::lowest());
    assert(std::isinf(negative_infinity3) && negative_infinity3 < std::numeric_limits<float>::lowest());
    assert(std::isinf(negative_infinity4) && negative_infinity4 < std::numeric_limits<float>::lowest());

    return EXIT_SUCCESS;
}

Ответ 2

Если std::numeric_limits<double>::is_iec559 - true, тогда его следует использовать в безопасном режиме -

double negative_infinity = - std::numeric_limits<double>::infinity();

(IEC559 - это эквивалент ISO IEEE754)

Если это false, тогда еще много работы, так как я не думаю, что С++-стандарт дает вам любую помощь.

Ответ 3

Я не знаю, какой компилятор использует, но вы можете использовать -std::numeric_limits<double>::infinity() на gcc и MinGw, чтобы увидеть Infinity-and-NaN. Кроме того, я запускал следующий код на MSVC, и он вернул значение true:

double infinity(std::numeric_limits<double>::infinity());
double neg_infinity(-std::numeric_limits<double>::infinity());
double lowest(std::numeric_limits<double>::lowest());

bool lower_than_lowest(neg_infinity < lowest);
std::cout << "lower_than_lowest: " << lower_than_lowest << std::endl;

Однако, возможно, стоит подумать о том, чтобы использовать низший в своем приложении вместо отрицательной бесконечности, поскольку это может привести к более переносимому решению.