Saltar al contenido

¿Cómo se almacenan los números de coma flotante en la memoria?

Solución:

Para comprender cómo se almacenan, primero debe comprender qué son y qué tipo de valores deben manejar.

A diferencia de los números enteros, un valor de punto flotante está destinado a representar valores extremadamente pequeños y extremadamente grandes. Para valores normales de coma flotante de 32 bits, esto corresponde a valores en el rango de 1.175494351 * 10 ^ -38 para 3.40282347 * 10 ^ + 38.

Claramente, usando solo 32 bits, no es posible almacenar todos los dígitos en tales números.

Cuando se trata de la representación, puede ver todos los números de punto flotante normales como un valor en el rango de 1.0 a (casi) 2.0, escalado con una potencia de dos. Entonces:

  • 1.0 es simplemente 1.0 * 2 ^ 0,
  • 2.0 es 1.0 * 2 ^ 1, y
  • -5,0 es -1.25 * 2 ^ 2.

Entonces, ¿qué se necesita para codificar esto, de la manera más eficiente posible? ¿Qué es lo que realmente necesitamos?

  • El signo de la expresión.
  • El exponente
  • El valor en el rango de 1.0 a (casi) 2.0. Esto se conoce como la “mantisa” o el significado.

Se codifica de la siguiente manera, de acuerdo con el estándar de coma flotante IEEE-754.

  • El signo es un solo bit.
  • El exponente se almacena como un entero sin signo, para valores de coma flotante de 32 bits, este campo es de 8 bits. 1 representa el exponente más pequeño y “todos unos – 1” el más grande. (0 y “todos unos” se utilizan para codificar valores especiales, ver más abajo.) Un valor en el medio (127, en el caso de 32 bits) representa cero, esto también se conoce como el parcialidad.
  • Al mirar la mantisa (el valor entre 1.0 y (casi) 2.0), uno ve que todos los valores posibles comienzan con un “1” (tanto en la representación decimal como binaria). Esto significa que no tiene sentido almacenarlo. El resto de los dígitos binarios se almacenan en un campo entero, en el caso de 32 bits este campo es de 23 bits.

Además de los valores normales de coma flotante, hay una serie de valores especiales:

  • El cero se codifica con exponente y mantisa como cero. El bit de signo se utiliza para representar “más cero” y “menos cero”. Un cero menos es útil cuando el resultado de una operación es extremadamente pequeño, pero aún es importante saber de qué dirección vino la operación.
  • más y menos infinito: representado mediante un exponente de “todos unos” y un campo de mantisa cero.
  • No es un número (NaN): se representa con un exponente de “todos unos” y una mantisa distinta de cero.
  • Números desnormalizados: números más pequeños que el número normal más pequeño. Representado mediante un campo de exponente cero y una mantisa distinta de cero. Lo especial de estos números es que la precisión (es decir, el número de dígitos que puede contener un valor) disminuirá cuanto menor sea el valor, simplemente porque no hay espacio para ellos en la mantisa.

Finalmente, el siguiente es un puñado de ejemplos concretos (todos los valores están en hexadecimal):

  • 1.0: 3f800000
  • -1234.0: c49a4000
  • 100000000000000000000000.0: 65a96816

En términos sencillos, es esencialmente una notación científica en binario. El estándar formal (con detalles) es IEEE 754.

  typedef struct {
      unsigned int mantissa_low:32;     
      unsigned int mantissa_high:20;
      unsigned int exponent:11;        
      unsigned int sign:1;
    } tDoubleStruct;

double a = 1.2;
tDoubleStruct* b = reinterpret_cast<tDoubleStruct*>(&a);

Es un ejemplo de cómo se configura la memoria si el compilador usa IEEE 754 de doble precisión, que es el valor predeterminado para un doble C en sistemas little endian (por ejemplo, Intel x86).

Aquí está en forma binaria basada en C y es mejor leer wikipedia sobre doble precisión para entenderlo.

¡Haz clic para puntuar esta entrada!
(Votos: 0 Promedio: 0)



Utiliza Nuestro Buscador

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *