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
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?
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.
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:
s
(indiquant si c'est positif ou négatif) - 1 bitm
(essentiellement les chiffres de votre numéro - 24 bitse
- 7 bitsEnsuite, 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
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.
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...
Flotteur brut 5.2:
01000000101001100110011001100110
^ sign bit
En mémoire, ordre inverse des octets (en tant que votre diagramme):
01100110011001101010011001000000
^ sign bit
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.
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....
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
int a;
float b=5.2;
memcpy(&a, &b, 4);
printf("%d",a);
Cela donne 0100 0000 1010 0110 0110 0110 1000 0001 (1084647041)
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
5.2 est représenté par "01000000101001100110011001100110"
Vérifiez l'applet Converter