2011-10-04 20 views
16

He leído que se almacenan en forma de mantisa y exponente¿Cómo se almacenan los números de coma flotante en la memoria?

He leído this document pero no podía entender nada.

+1

El documento se ha vinculado a lo explica con bastante claridad. ¿Qué encuentras específicamente difícil de entender? –

+1

@MichaelBorgwardt No, NO ES claro. Explica cómo se almacena el exponente DESPUÉS de introducir un problema que necesita esta explicación ('¿Pero y si el número es cero?' ... 'Oh querido'). Es como esas historias de crímenes donde el truco es que no te mostraron toda la información, pero el personaje principal de la historia los conoce a todos. – xanatos

Respuesta

25

Para comprender cómo se almacenan, primero debe entender lo que son y qué tipo de valores que están destinados a manejar.

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

Claramente, usando solo 32 bits, no es posible almacenar cada dígito en dichos 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, con escala con una potencia de dos. Entonces 1.0 es, simplemente 1.0 * 2^0. 2.0 es 1.0 * 2^1. -5.0 es -1.25 * 2^2.

Entonces, ¿eso es necesario 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", es decir, significando.

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

  • El signo es de 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 los uno - 1" el más grande. (0 y "todos unos" se utilizan para codificar valores especiales, ver a continuación.) Un valor en el medio (127, en el caso de 32 bits) representa cero, esto también se conoce como sesgo.
  • 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 punto flotante, hay una serie de valores especiales:

  • Zero está codificado con tanto exponente y mantisa como cero. El bit de signo se usa para representar "más cero" y "menos cero". Un cero negativo es útil cuando el resultado de una operación es extremadamente pequeño, pero aún es importante saber de qué dirección proviene la operación.
  • infinito más y menos - representado mediante un exponente "todos unos" y un campo de mantisa cero.
  • No es un número (NaN) - representado mediante un exponente "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 usando un campo de exponente cero y una mantisa distinta de cero. Lo especial con estos números es que la precisión (es decir, el número de dígitos que un valor puede contener) 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 hex):

  • 1,0: 3f800000
  • -1234,0: c49a4000
  • 100000000000000000000000,0: 65a96816
6

En términos simples, es esencialmente scientific notation en binario. El estándar formal (con detalles) es IEEE 754.

+5

+1 pero un Wiki no es un estándar formal, es como mucho la explicación de un estándar formal :-) :-) – xanatos

+4

Y C no requiere IEEE floating-poimt. –

3
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 la memoria está configurado si compilador utiliza IEEE 754 de doble precisión que es el valor predeterminado para un doble C en la mayoría de los sistemas de hoy en día.

Aquí está en formato binario en C y mejor lea para entenderlo.

+1

Esa es una posibilidad, pero no la única. –

2

Existen varios formatos de coma flotante diferentes. La mayoría de ellos comparten algunas características comunes: un bit de signo, algunos bits dedicados a almacenar un exponente y algunos bits dedicados a almacenar el significado (también llamado mantisa).

El estándar de coma flotante IEEE intenta definir un único formato (o más bien conjunto de formatos de algunos tamaños) que se puede implementar en una variedad de sistemas. También define las operaciones disponibles y su semántica. Se entiende bastante bien, y la mayoría de los sistemas con los que probablemente te encuentres probablemente utilicen el punto flotante IEEE. Pero otros formatos todavía están en uso, así como las implementaciones IEEE que no son del todo completas. El estándar C proporciona soporte opcional para IEEE, pero no lo ordena.

1

La mantisa representa los bits más significativos del número.

El exponente representa cuántos cambios se van a realizar en la mantisa para obtener el valor real del número.

La codificación especifica cómo se representa el signo de mantisa y el signo de exponente (básicamente si se desplaza hacia la izquierda o hacia la derecha).

El documento al que se refiere especifica la codificación IEEE, la más utilizada.

0

Es una implementación definida, aunque IEEE-754 es la más común por ahora.

para asegurarse de que se utiliza IEEE-754:

  • en C, utilice #ifdef __STDC_IEC_559__
  • en C++, utilice los std::numeric_limits<float>::is_iec559 constantes
Cuestiones relacionadas