Cómo representar el número de FLOAT en la memoria en C

Mientras leía un tutorial, encontré cómo representar el número de Float en la memoria. El tutorial tenía un ejemplo con un número de punto flotante.

float a=5.2 with below Diagram 

enter image description here

¿Puede alguien decir cómo se convierte este 5.2 en binario y cómo se representa en la memoria en el diagtwig anterior?

Como se dijo, 5.2 se representa como un bit de signo, un exponente y una mantisa. ¿Cómo codifica 5.2?

5 es fácil:

 101. 

El rest, 0.2 es 1/5, entonces divide 1.00000... (hex) por 5 y obtienes 0.3333333... (hex).

(Esto se puede seguir más fácilmente si se considera un poco menos: 0.FFFF...F / 5 = 3 , por lo que es fácil ver que 0.FFFF... / 5 = 0.33333... Ese El bit faltante no importa cuando se divide por 5, entonces 1.0000... / 5 = 0.3333... también).

Eso debería darte

 0.0011001100110011001100110011... 

Agrega 5 y obtienes

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

Ahora desplácese hacia la derecha (normalícelo, es decir, asegúrese de que el bit superior esté justo antes del punto decimal) y ajuste el exponente en consecuencia:

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

Ahora solo tiene que agregar el sesgo de 127 (es decir, 129 = 0b10000001 ) al exponente y almacenarlo:

 0 10000001 1010 0110 0110 0110 0110 0110 

Olvídese de la parte superior 1 de la mantisa (que siempre se supone que es 1, a excepción de algunos valores especiales, por lo que no se almacena), y obtiene:

 01000000 10100110 01100110 01100110 

Ahora solo tienes que decidir little o big endian.

Esto no es exactamente cómo funciona, pero eso es más o menos lo que sucede cuando un número como 5.2 se convierte en binario.

Creo que el diagtwig no es un cien por ciento correcto.

Los flotantes se almacenan en la memoria de la siguiente manera:

Se descomponen en:

  • signo s (que denota si es positivo o negativo) – 1 bit
  • mantisa m (esencialmente los dígitos de su número – 24 bits
  • exponente e – 7 bits

Luego, puede escribir cualquier número x como s * m * 2^e donde ^ denota exponenciación.

5.2 debe representarse de la siguiente manera:

 0 10000001 01001100110011001100110 SEM 

S=0 indica que es un número positivo, es decir s=+1

E se debe interpretar como número sin signo, representando 129 . Tenga en cuenta que debe restar 127 de E para obtener el exponente original e = E - 127 = 2

M debe interpretarse de la siguiente manera: se interpreta como un número que comienza con un 1 seguido de un punto ( . ) Y luego dígitos después de ese punto. Los dígitos después son los que en realidad están codificados en m . Introducimos pesos para cada dígito:

 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) 

Ahora sum los pesos donde se establecen los bits correspondientes. Después de hacer esto, agregue 1 (debido a la normalización en el estándar IEEE, siempre agregue 1 para interpretar M ) y obtenga el m original.

Ahora, calcula x = s * m * 2^e obtiene su número original.

Entonces, lo único que queda es que en la memoria real, los bytes pueden estar en orden inverso. Es por eso que el número no puede almacenarse de la siguiente manera:

 0 10000001 01001100110011001100110 SEM 

pero más al revés (simplemente tome bloques de 8 bits y duplique su orden)

 01100110 01100110 10100110 01000000 MMMMMMMM MMMMMMMM EMMMMMMM SEEEEEEE 

El valor se representa en la memoria en orden inverso, pero el punto confuso puede ser que 5.2f se representa realmente como 5.1999998 debido a la pérdida de exactitud de los valores de coma flotante.

Representar 5.2 es muy simple en lógica binaria:

  8 4 2 1 5 -> 0 1 0 1 

Para un número decimal:

Tome .2 y multiplique por 2 (ya que está representado en binario).

 .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 

y así…

Después de este paso, tome el valor antes del punto decimal de la salida de los pasos anteriores:

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

Entonces, la o / p final de 5.2 es:

 0101.00110... 

Flotador crudo 5.2:

 01000000101001100110011001100110 ^ sign bit 

En memoria, orden inverso de bytes (como su diagtwig):

 01100110011001101010011001000000 ^ sign bit 

5.2

El número se almacena en forma de “Bit de signo, exponente, Mantissa. En forma binaria de 5 es 8 4 2 1 entonces 0101 y .2 es

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

y el bit de signo 0 porque el número es positivo.

 0 0101 001.... 

5.2 en binario 101.00110011 …… ——> forma no normalizada 5.2 es .10100110011 …. x 2 ^ 3 ——> forma normal explícita 5.2 es .0100110011 x 2 ^ 3 en forma implícita normal

aquí el bit de signo se convierte en 0 (porque el número es positivo) y el exponente es de siete bits, por lo que usa una notación excedente de 64 exponentes para que el exponente se convierta en 64 + 3 = 69, es decir, 1000101 y quedará mantissa (total 32bit – 7 bit de signo = 24 bit) 0100 1100 1100 1100 1100 1100

En el ejemplo anterior, el bit de signo es correcto. El exceso 64 no se aplica, por lo que no se normaliza, pero idealmente debería usar implícitamente la parte Mantisa de normalización en el segundo byte. Si aplica la normalización implícita, el MSB ‘1’ no vendrá.

5.2 se representa como “01000000101001100110011001100110”

Compruebe el Applet Converter

La técnica de conversión publicada originalmente en el otro sitio web se muestra innecesariamente compleja (aunque nos lleva a la respuesta correcta). Para la representación de la memoria de 5.2 en la memoria:

Primero conviértalo en un simple sistema binario, que nos dará 101.001100110011001100110011

Ahora cámbielo a forma científica: 1.01001100110011001100110011 x 10 ^ 2.

Ahora nuestro bit de signo es 0 ya que el número es positivo

Para el exponente necesitamos (127 + 2) hasta 8 bits, lo que nos da 10000001

La fracción es 01001100110011001100110. (23 bits) (Descartando el 1 principal de forma científica)

=> la representación es

0 10000001 0100 1100 1100 1100 1100 110

Debajo de dos referencias realmente me ayudó a entender la encoding de números en coma flotante IEE 754 en formato binario,

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

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

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

Esto da 0100 0000 1010 0110 0110 0110 1000 0001 (1084647041)