2010-07-17 9 views
8

je tentais de comprendre la représentation à virgule flottante en C en utilisant ce code (les deux float et int sont 4 octets sur ma machine):Représentation du flotteur en C

int x = 3; 
float y = *(float*) &x; 
printf("%d %e \n", x, y); 

Nous savons que la représentation binaire de x seront les suivants

00000000000000000000000000000011

Par conséquent, je me serais attendu à y être représentée comme suit

  • bit de signe (premier bit de gauche à droite) = 0

  • Exponent (bits 2-9 de gauche à droite) = 0

  • mantisse (bits 10-32): 1 + 2^(-22)+2^(-23)

menant à y = (-1)^0 * 2^(0-127) * (1+2^(-22) + 2^(-23)) = 5.87747E-39

Mon programme imprime cependant

3 4.203895e-45

C'est, y a la valeur 4.203895e-45 au lieu de 5.87747E-39 comme je m'y attendais. Pourquoi cela arrive-t-il. Qu'est-ce que je fais mal?

P.S. J'ai également imprimé les valeurs directement à partir de gdb, donc ce n'est pas un problème avec la commande printf.

+5

http://en.wikipedia.org/wiki/Single_precision_floating-point_format – kennytm

+0

Sur quelle machine essayez-vous cela?Quelle est l'ordre des octets de l'hôte? Big endian? Petit endian? – Dirk

+0

x86_64 machine linux. Petit endian. – Siggi

Répondre

12

Les nombres à virgule flottante IEEE avec des champs d'exposant de 0 sont «dénormalisés». Cela signifie que le 1 implicite devant la mantisse n'est plus actif. Cela permet de représenter de très petits nombres. Voir This wikipedia article for more explanation. Dans votre exemple, le résultat serait 3 * 2^-149

1

En détails, il est décrit http://en.wikipedia.org/wiki/IEEE_754-2008 Cette norme suppose que vous déplacez la mantisse gauche jusqu'à cacher le premier bit de sens (exposant croissant). Dans votre cas yo l'expression 1 + 2^(- 23) - alors vous obtenez la bonne réponse 4.9..E-32

+0

Pourriez-vous montrer travailler pour votre réponse? Il ne semble pas correct de simplement brancher 1 + 2^(- 23) OU la bonne réponse est 4.9E-32. – freespace

6

-127 dans l'exposant est réservé aux nombres dénormalisés. Votre calcul est pour les nombres normalisés tandis que votre flotteur est un flotteur dénormalisé.

numéros dénormalisé sont calculés selon une méthode similaire, mais:

  1. exposant est -126
  2. bit de tête implicite ne suppose plus

Donc cela signifie que le calcul est plutôt:

(-1)**0*2**(-126)*(2**(-22)+2**(-23)) = 4.2038953929744512e-45 

Ce qui précède est python, où ** mea ns identique à ^