web-dev-qa-db-fra.com

Comment représenter le numéro FLOAT en mémoire en C

En lisant un tutoriel, je suis parvenu à comprendre comment représenter le nombre flottant en mémoire. Le tutoriel avait un exemple avec un nombre à virgule flottante. 

   float a=5.2  with below Diagram

enter image description here

Quelqu'un peut-il dire s'il vous plaît comment cette 5.2 est convertie en binaire et comment elle est représentée en mémoire dans le diagramme ci-dessus?

37
Amit Singh Tomar

Comme il a été dit, 5.2 est représenté par un bit de signe, un exposant et une mantisse. Comment encodez-vous la 5.2? 

5 est facile: 

101. 

Le reste, 0.2 est 1/5, divisez donc 1.00000... (hex) par 5 et vous obtiendrez 0.3333333... (hex). 

(Cela peut être suivi plus facilement si vous considérez un bit de moins: 0.FFFF...F / 5 = 3, il est donc facile de voir que 0.FFFF... / 5 = 0.33333.... Ce bit manquant n'a pas d'importance si vous divisez par 5, donc 1.0000... / 5 = 0.3333... aussi.  

Cela devrait vous donner 

0.0011001100110011001100110011... 

Ajoutez 5 et vous obtenez 

101.00110011001100110011...         exp 0    (== 5.2 * 2^0)

Déplacez-le maintenant correctement (normalisez-le, c’est-à-dire assurez-vous que le bit du haut est juste avant le point décimal) et ajustez l’exposant en conséquence:

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

Maintenant, il suffit d’ajouter le biais de 127 (c.-à-d. 129 = 0b10000001) à l’exposant et de le stocker:

0 10000001 1010 0110 0110 0110 0110 0110 

Oubliez le premier 1 de la mantisse (qui est toujours supposé être 1, à l'exception de certaines valeurs spéciales, de sorte qu'il n'est pas stocké) et vous obtenez:

01000000 10100110 01100110 01100110

Il ne reste plus qu’à décider petit ou grand endian.

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

49
Rudy Velthuis

Je pense que le diagramme n’est pas correct à un centième de centime.

Les flotteurs sont stockés en mémoire comme suit:

Ils sont décomposés en:

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

Ensuite, vous pouvez écrire le nombre x sous la forme s * m * 2^e, où ^ désigne une 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é comme un nombre non signé, représentant ainsi 129. Notez que vous devez soustraire 127 de E pour obtenir l’exposant original e = E - 127 = 2

M doit être interprété de la manière suivante: Il est interprété comme un nombre commençant par un 1 suivi d'un point (.), suivi de chiffres après ce point. Les chiffres après . sont ceux qui sont réellement codés dans m. Nous introduisons des 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écapitulez les poids où les bits correspondants sont définis. Ensuite, vous ajoutez 1 (en raison de la normalisation dans la norme IEEE, vous ajoutez toujours 1 pour interpréter M) et vous obtenez l'original m.

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

Ainsi, la seule chose qui reste est que dans la mémoire réelle, les octets peuvent être dans l’ordre inverse. C'est pourquoi le numéro ne peut pas être enregistré comme suit:

0 10000001 01001100110011001100110    
S    E               M

mais plutôt l'inverse (prenez simplement des blocs de 8 bits et reproduisez leur ordre)

01100110 01100110 10100110 01000000
MMMMMMMM MMMMMMMM EMMMMMMM SEEEEEEE
47
phimuemue

La valeur est représentée en mémoire dans l'ordre inverse, mais le point de confusion peut être que 5.2f soit réellement représentée par 5.1999998 en raison de la perte de précision des valeurs en virgule flottante.

6
beren

Représenter la 5.2 est très simple en logique binaire:

     8 4 2 1
5 -> 0 1 0 1

Pour un nombre décimal:

Prendre 0,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

etc...

Après cette étape, prenez la valeur avant le point décimal de la sortie des étapes ci-dessus:

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

Donc, le dernier o/p de 5.2 est:

0101.00110...
4
vijayanand1231

Flotteur brut 5.2:

01000000101001100110011001100110
^ sign bit

En mémoire, ordre inverse des octets (en tant que votre diagramme):

01100110011001101010011001000000
                        ^ sign bit
3
user703016

5.2 en binaire 101.00110011 ...... ------> forme non normalisée 5.2 est .10100110011 .... x 2 ^ 3 ------> forme normale explicite 5.2 est .0100110011 x 2 ^ 3 sous forme normale implicite

ici, le bit de signe devient 0 (car le nombre est positif) et exposant est sept bits donc il utilise excès de notation 64 exposants so exposant deviendra 64 + 3 = 69 c'est-à-dire 1000101 et le reste sera mantissa (total 32 bits - 7 exposants - 1 bit de signe = 24 bits) 0100 1100 1100 1100 1100 1100

Dans l'exemple ci-dessus, le bit de signe est correct L'excédent 64 n'est pas appliqué; il ne doit donc pas être normalisé, mais il devrait idéalement utiliser une normalisation implicite. 

1
JOBBINE

5.2

Le nombre est stocké sous la forme "Sign Bit, Exponent, Mantissa . Sous forme binaire de 5 est 8 4 2 1 donc 0101

.2*2=.4   0
.4*2=.8   0
.8*2=1.6  1

et signez le bit 0 car le nombre est positif.

0 0101 001....
1
shivaji kapale

La technique de conversion publiée à l’origine sur l’autre site Web est illustrée inutilement complexe (bien que cela nous prenne au juste) Pour la représentation mémoire de 5.2 en mémoire:

D'abord, convertissez-le en système binaire simple, ce qui nous donnera 101.001100110011001100110011 

Maintenant changez-le en forme scientifique: 1.01001100110011001100110011 x 10 ^ 2. 

Maintenant, notre bit de signe est 0 car le nombre est positif

Pour exposant nous avons besoin de (127 + 2) jusqu’à 8 bits ce qui nous donne 10000001

La fraction est 01001100110011001100110. (23 bits) (Supprimer le premier 1 de la forme scientifique)

=> la représentation est 

0 10000001 0100 1100 1100 1100 1100 110

0
Mojo Jojo
int a;
float b=5.2;
memcpy(&a, &b, 4);
printf("%d",a);

Cela donne 0100 0000 1010 0110 0110 0110 1000 0001 (1084647041)

0
Nahashon M

Deux références ci-dessous m'ont vraiment aidée à comprendre le codage de nombres à virgule flottante IEE 754 au format binaire,

http://www.pitt.edu/~juy9/142/slides/L3-FP_Representation.pdf

http://en.wikipedia.org/wiki/Single-precision_floating-point_format

0
Harish

5.2 est représenté par "01000000101001100110011001100110"

Vérifiez l'applet Converter

0
stacker