27 votes

Comment représenter le FLOTTEUR numéro en mémoire dans le C

Lors de la lecture d'un tutoriel, je suis tombé sur la façon de représenter des nombre à virgule en mémoire. Le tutoriel a eu un exemple avec un nombre à virgule flottante.

   float a=5.2  with below Diagram

enter image description here

Quelqu'un peut s'il vous plaît dites comment cette 5.2 est converti en binaire, et la façon dont il est représenté en mémoire ci-dessus dans le schéma ci-dessus?

36voto

phimuemue Points 11644

Je pense que le diagramme n'est pas un centaines pour cent correct.

Les flotteurs sont stockées dans la mémoire comme suit:

Ils sont décomposés en:

  • signe s (indiquant si il est positif ou négatif) - 1 bits
  • mantisse m (essentiellement les chiffres de votre numéro - 24 bits
  • exposant e - 7 bits

Ensuite, vous pouvez écrire n'importe quel nombre x comme s * m * 2^e^ dénote l'exponentiation.

5.2 devrait être représenté comme suit:

0 10000001 01001100110011001100110    
S    E               M

S=0 indique qu'il s'agit d'un nombre positif, c'est à dire s=+1

E , doit être interprété en nombre non signé, représentant ainsi 129. Notez que vous devez soustraire 127 de E pour obtenir l'original de l'exposant e = E - 127 = 2

M doivent être interprétées de la façon suivante: Elle est interprétée comme un numéro commençant par un 1 suivi d'un point (.), puis de chiffres après le point. Les chiffres après . sont ceux qui sont réellement codé en m. Nous introduisons les poids pour chaque chiffre:

bits in M: 0   1    0     0      1       ... 
weight:    0.5 0.25 0.125 0.0625 0.03125 ... (take the half of the previous in each step)

Maintenant vous résumer le poids où les bits correspondants sont fixés. Après vous avez fait cela, vous ajoutez 1 (en raison de la normalisation dans le standard IEEE, vous pouvez toujours ajouter 1 pour interpréter M) et d'obtenir les originaux m.

Maintenant, vous calculez x = s * m * 2^e et obtenir votre numéro d'origine.

Donc, la seule chose qui reste est que dans la vraie mémoire, octets peuvent être dans l'ordre inverse. C'est pourquoi le nombre ne peut pas être stocké comme suit:

0 10000001 01001100110011001100110    
S    E               M

mais plus dans l'autre sens (il suffit de prendre 8-bits des blocs et miroir de leur ordre)

01100110 01100110 10100110 01000000
MMMMMMMM MMMMMMMM EMMMMMMM SEEEEEEE

35voto

Rudy Velthuis Points 11477

Comme il a été dit, 5.2 est représenté par un bit de signe, l'exposant et la mantisse. Comment encoder 5.2?

5 est facile:

101. 

Le reste, de 0,2 est de 1/5, donc le diviser 0.FFFFFFF... (hex) par 5 (ou 1.00000... (hex)) et vous obtiendrez 0.3333333... (hex).

Cela devrait vous donner

0.0011001100110011001100110011... 

Ajouter 5, et vous obtenez

101.00110011001100110011...                  (5.2 * 2^0)

Maintenant shift et ajuster l'exposant

1.010011001100110011001100110011... exp +2   (1.3 * 2^2)

Maintenant, vous n'avez qu'à ajouter le biais de 127 (c - 129 = 0b10000001) de l'exposant et de la stocker:

0 10000001 1010 0110 0110 0110 0110 0110 

Oubliez le top 1 de la mantisse (qui est toujours censé être de 1, sauf pour certaines valeurs particulières, de sorte qu'il n'est pas stocké), et vous obtenez:

01000000 10100110 01100110 01100110

Maintenant, vous n'avez qu'à décider little ou big endian.

Ce n'est pas exactement comment cela fonctionne, mais c'est plus ou moins ce qui se passe lorsqu'un nombre comme 5.2 est converti en binaire.

6voto

beren Points 116

La valeur est représentée en mémoire dans l'ordre inverse, mais la confusion peut être que 5,2 f est vraiment représenté comme 5.1999998 en raison de la précision de la perte des valeurs à virgule flottante.

3voto

Cicada Points 19550

Raw float 5.2:

01000000101001100110011001100110
^ sign bit

Dans la mémoire, inverser l'ordre des octets (comme votre diagramme):

01100110011001101010011001000000
                        ^ sign bit

2voto

abababa Points 110

Représentant 5.2 est très simple dans une logique binaire:

     8 4 2 1
5 -> 0 1 0 1

Pour un nombre décimal:

Prendre .2 et multiplier par 2 (car il est représenté en binaire).

.2 X 2 = 0.4 -> take the value after the
                decimal point, don't take the value before
                the decimal point

.4 X 2 = 0.8
.8 X 2 = 1.6
.6 X 2 = 1.2
.2 X 2 = 0.4

et ainsi de suite...

Après cette étape, prendre les valeurs avant la virgule point de sortie de la procédure ci-dessus:

.2 X 2 = 0.4 -> take 0 from this for representing in binary form

Donc la finale de la s/p de 5.2 est:

0101.00110...

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X