2010-03-29 9 views
7

J'utilise MSVC++, et je veux utiliser la valeur spéciale INFINITY dans mon code.Infinity dans MSVC++

Quel est le modèle d'octets ou la constante à utiliser dans MSVC++ pour l'infini?

Pourquoi 1.0f/0.0f semble avoir la valeur 0?

#include <stdio.h> 
#include <limits.h> 

int main() 
{ 
    float zero = 0.0f ; 
    float inf = 1.0f/zero ; 

    printf("%f\n", inf) ; // 1.#INF00 
    printf("%x\n", inf) ; // why is this 0? 

    printf("%f\n", zero) ; // 0.000000 
    printf("%x\n", zero) ; // 0 

} 

Répondre

19

utilisation numeric_limits:

#include <limits> 

float maxFloat = std::numeric_limits<float>::infinity(); 
+1

Neat! Comment cela marche-t-il? Est-ce correct d'attribuer quelque chose 'numeric_limits :: infinity()'? Quel est le modèle de bits pour INFINITY? Comment sait-il si le motif est apparemment 0 dans mon exemple? – bobobobo

+1

@bobobobo: Lorsque vous traitez une variable comme quelque chose qui n'est pas dans 'printf', il n'y a pas grand chose à espérer, cela pourrait casser. Je pense que peterchen le couvre. – GManNickG

11

printf("%x\n", inf) attend un nombre entier (32 bits sur MSVC), mais reçoit un double. L'hilarité s'ensuivra. Err, je veux dire: comportement indéfini.

(Et oui, il reçoit un double puisque pour une liste d'arguments variables, les flotteurs sont promus en double).

Modifiez tout de même, vous devez utiliser numeric_limits, comme le dit aussi l'autre réponse.

2

C'est ce qui arrive quand vous mentez à printf(), il se trompe. Lorsque vous utilisez le spécificateur de format% x, il s'attend à ce qu'un entier soit passé sur la pile, et non à un flottant transmis sur la pile FPU. Correction:

printf("%x\n", *(__int32*)&inf) ; 

Vous pouvez obtenir l'infini sur le <limits> fichier d'en-tête C de:

float inf = std::numeric_limits<float>::infinity(). 
3

Dans les arguments variables liste pour printf, flotteurs promus au double. La représentation octet little-endian de l'infini en tant que double est 00 00 00 00 00 00 F0 7F.

Comme peterchen mentionné, "% x" attend un int, pas un double. Ainsi, printf ne regarde que les premiers sizeof (int) octets de l'argument. Aucune version de MSVC++ ne définit int pour être plus grand que 4 octets, donc vous obtenez tous les zéros.