web-dev-qa-db-fra.com

Infini négatif

J'essaie de comprendre comment attribuer la valeur de l'infini négatif à une variable flottante ou double. Il semble que, y compris les limites de bibliothèque standard, je peux obtenir la représentation à l'infini, et je sais (très certainement) que l'ajout d'un moins devant (-infinity) pourrait entraîner la valeur que je recherche dans le virgule flottante IEEE754 standard (comme 0x7FFFFFFF pourrait résulter sur 0xFFFFFFFF), mais je ne suis même pas sûr de cela, sans parler d'autres normes qui pourraient être là-bas (s'il y en a). Je trouve cela vraiment, vraiment non professionnel et dépendant de la mise en œuvre.

Existe-t-il un bon moyen d'obtenir la valeur de la plate-forme infinie négative et de la mise en œuvre indépendamment, bien sûr, sinon je pourrais tout aussi bien utiliser un #define, tout le monde aime le prétraitement.

34
Setzer22

Au moins si std :: numeric_limits :: is_iec559 (IEEE 754) est vrai (ce qui garantit que std :: numeric_limits :: has_infinity est également vrai), vous pouvez exprimer l'infini positif et négatif valorise comme vous l'avez déjà dit.

Brève explication des valeurs infinies IEEE 754-1985 de Wikipedia :

......couper......

Le champ d'exposant biaisé est rempli de tous les 1 bits pour indiquer l'infini ou un résultat invalide d'un calcul.

Infini positif et négatif

L'infini positif et négatif sont représentés ainsi:

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

......couper......

Assertions

L'exemple suivant fonctionnera comme prévu ou provoquera une erreur de temps de compilation au cas où la plate-forme cible ne prend pas en charge les flottants 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;
}
29
Sam

Si std::numeric_limits<double>::is_iec559 Est true alors il devrait être sûr d'utiliser -

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

(IEC559 est l'équivalent ISO de IEEE754)

Si c'est false alors il y a beaucoup plus de travail à faire car je ne pense pas que la norme C++ vous aide.

7
Ian Cook

Je ne sais pas quel compilateur vous utilisez, mais vous pouvez utiliser -std::numeric_limits<double>::infinity() sur gcc et MinGw voir Infinity-and-NaN . J'ai également exécuté le code suivant sur MSVC et il est retourné vrai:

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;

Cependant, il peut être utile d'envisager d'utiliser le plus bas dans votre application au lieu de l'infini négatif, car cela entraînera probablement une solution plus portable.

5
kenba