Pergunta

Estou tentando descobrir como atribuir o valor de infinito negativo a uma variável flutuante ou dupla.Parece que incluindo os limites da biblioteca padrão, posso obter a representação do infinito e sei (com certeza) que adicionar um sinal de menos na frente disso (-infinity) pode resultar no valor que estou procurando no ponto flutuante IEEE754 padrão (como 0x7FFFFFFF pode resultar em 0xFFFFFFFF), mas nem tenho certeza disso, sem mencionar outros padrões que possam estar por aí (se houver algum).Acho que é muito, muito pouco profissional e dependente da implementação.

Existe uma boa maneira de obter o valor da plataforma infinita negativa e da implementação de forma independente, é claro, caso contrário, seria melhor usar um #define, todo mundo gosta de pré-processamento.

Foi útil?

Solução

Pelo menos se std::numeric_limits::is_iec559 (IEEE 754) é verdade (o que garante, que std::numeric_limits::has_infinity também é verdade), você pode expressar valores infinitos positivos e negativos da maneira que já declarou.

Breve explicação dos valores infinitos IEEE 754-1985 de Wikipédia:

......recorte......

O campo de expedição tendencioso é preenchido com todos os 1 bits para indicar o infinito ou um resultado inválido de um cálculo.

Infinito positivo e negativo

O infinito positivo e negativo são representados assim:

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

......recorte......

Asserções

O exemplo a seguir funcionará conforme esperado ou causará um erro de tempo de compilação caso a plataforma de destino não suporte flutuadores 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;
}

Outras dicas

Se std::numeric_limits<double>::is_iec559 é true então deve ser seguro usar -

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

(IEC559 é o equivalente ISO de IEEE754)

Se é false então há muito mais trabalho a fazer, pois não acho que o padrão C++ lhe ajude em nada.

Não sei qual compilador você está usando, mas você pode usar -std::numeric_limits<double>::infinity() no gcc e MinGw veja Infinito e NaN.Também executei o seguinte código no MSVC e ele retornou verdadeiro:

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;

No entanto, talvez valha a pena considerar usar o valor mais baixo em seu aplicativo, em vez do infinito negativo, pois é provável que resulte em uma solução mais portátil.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top