Para comprender el rango de valores y la precisión de cálculo de float y double, primero es necesario entender cómo se almacenan los números decimales en la computadora:
Por ejemplo: 78.375 es un decimal positivo. Para almacenar este número en la computadora, es necesario representarlo en formato de número de punto flotante; primero se realiza la conversión binaria:
Nota: el punto decimal en binario es diferente del punto decimal en decimal. Después del punto decimal en binario están las potencias negativas de 2; en decimal, las potencias negativas de 10.
1. Conversión binaria de decimales (números de punto flotante)
La parte entera de 78.375:
La parte fraccionaria:
Por lo tanto, la forma binaria de 78.375 es 1001110.011
Luego, usandonotación científica binaria, se tiene:
Observa que el número representado en notación científica binaria después de la conversión tiene base, exponente y parte fraccionaria; esto se llamanúmero de punto flotante
2. Almacenamiento de números de punto flotante en la computadora
En la computadora, para guardar este número se utiliza la representación de punto flotante, que se divide en tres partes principales:
La primera parte se usa para almacenar elbit de signo (sign),que se usa para distinguir entre positivo y negativo; aquí es 0, lo que indica un número positivo.
La segunda parte se usa para almacenar elexponente (exponent),aquí el exponente es 6 en decimal.
La tercera parte se usa para almacenar lafracción (fraction),aquí la parte fraccionaria es 001110011.
Cabe señalar que el exponente también puede ser positivo o negativo; esto se explicará más adelante.Como se muestra en la siguiente figura:

Por ejemplo, el tipo float es de 32 bits, que es la representación de punto flotante de precisión simple:
El bit de signo (sign) ocupa 1 bit y se usa para representar números positivos y negativos.
El campo del exponente (exponent) ocupa 8 bits y se usa para representar el exponente.
El campo de la fracción (fraction) ocupa 23 bits y se usa para representar la fracción; si faltan bits, se rellenan con 0.
El tipo double, en cambio, es de 64 bits y es la representación de punto flotante de doble precisión:
El bit de signo ocupa 1 bit, el campo del exponente ocupa 11 bits y el campo de la fracción ocupa 52 bits.
En este punto ya se puede vislumbrar:
El campo del exponente determina el rango de magnitud,porque cuanto mayor sea el número que pueda representar el campo del exponente, mayor será el número que se puede representar.
El campo de la fracción determina la precisión de cálculo,porque cuanto mayor sea el número que pueda representar el campo de la fracción, mayor será la precisión de cálculo.
Quizá todavía no quede claro; veamos un ejemplo:
El campo de la fracción de float tiene solo 23 bits, es decir, 23 bits binarios; el mayor número decimal que puede representar es 2 elevado a 23, es decir, 8388608, que tiene 7 dígitos decimales. Estrictamente, la precisión solo puede garantizar al 100 % operaciones con 6 dígitos decimales.
El campo de la fracción de double tiene 52 bits; el valor decimal máximo correspondiente es 4 503 599 627 370 496, que tiene 16 dígitos, por lo que la precisión de cálculo solo puede garantizar al 100 % operaciones con 15 dígitos decimales.
Nota: las calculadoras científicas comunes, como las que usábamos en la secundaria, generalmente admiten como máximo 15 dígitos para las operaciones; más allá de eso no son precisas. En la programación real, también se usa más el tipo double porque puede garantizar 15 dígitos. Si se necesitan operaciones de mayor precisión, hay que usar otros tipos de datos, como el tipo BigDecimal de Java, que puede admitir operaciones de mayor precisión.
3. Desplazamiento del campo del exponente y representación sin signo
Hay que tener en cuenta que el exponente puede ser negativo o positivo, es decir,el exponente es un entero con signo,y las operaciones con enteros con signo son más problemáticas que con enteros sin signo. Por eso, para evitar problemas innecesarios, al almacenar el exponente es necesario convertirlo aentero sin signo.Entonces, ¿cómo se hace la conversión?
Observa que el campo del exponente de float tiene 8 bits, por lo que el rango de valores del exponente es de -126 a +127. Para eliminar el impacto de los números negativos en los cálculos reales (como comparar tamaños, sumar y restar, etc.), al almacenar realmente el exponente se puede hacer un mapeo simple y sumar undesplazamiento (offset),por ejemplo, el desplazamiento del exponente de float es 127, así no aparecerán números negativos.
Por ejemplo:
Si el exponente es 6, entonces lo que realmente se almacena es 6+127=133, es decir, se convierte 133 a binario y luego se almacena.
Si el exponente es -3, entonces lo que realmente se almacena es -3+127=124, es decir, se convierte 124 a binario y luego se almacena.
Cuando necesitemos calcular el número decimal real representado, basta con restar el desplazamiento al exponente.
Para el tipo double correspondiente, el desplazamiento del exponente al almacenar es 1023.
4. Para finalizar
Por lo tanto, si se usa el tipo float para guardar el decimal 78.375, primero hay que convertirlo a punto flotante y se obtieneel bit de signo,yel exponente,yla parte fraccionaria.Este ejemplo ya se ha analizado antes, por lo tanto:
El bit de signo es 0, el campo del exponente es 6+127=133, cuya representación binaria es 10 000 101; la parte fraccionaria es 001110011; para la parte insuficiente, complete automáticamente con 0.
Unidos y representados con float, la parte en negrita es el campo del exponente y el bit más a la izquierda es 0, que representa un número positivo:
0 10000101 001110011 00000 00000 0000
Si se usa double para guardarlo... calcúlalo tú mismo, hay demasiados 0.
Autor: Boss呱呱
Enlace: https://www.zhihu.com/question/46432979/answer/221485161