precisión float doble convertidor types floating-point double ieee-754

types - float - precisión doble 64 bits



mayor número entero que se puede almacenar en un doble (7)

¿Cuál es el entero más grande "sin flotación" que se puede almacenar en un tipo doble IEEE 754 sin perder precisión?



El entero más grande / más grande que se puede almacenar en un doble sin perder precisión es el mismo que el valor más grande posible de un doble. Es decir, DBL_MAX o aproximadamente 1.8 × 10 308 (si su doble es un doble IEEE 754 de 64 bits). Es un número entero. Está representado exactamente. ¿Qué más quieres?

Continúa, pregúntame cuál es el número entero más grande, de modo que este y todos los enteros más pequeños se puedan almacenar en dobles IEEE de 64 bits sin perder precisión. Un doble IEEE de 64 bits tiene 52 bits de mantisa, así que creo que es 2 53 :

  • 2 53 + 1 no pueden almacenarse, porque 1 al comienzo y 1 al final tienen demasiados ceros en el medio.
  • Se puede almacenar algo menos que 2 53 , con 52 bits almacenados explícitamente en la mantisa, y luego el exponente en efecto le da otro.
  • 2 53 obviamente se pueden almacenar, ya que es una pequeña potencia de 2.

O bien, otra forma de verlo: una vez que el sesgo ha sido quitado del exponente, e ignorando el bit de signo como irrelevante para la pregunta, el valor almacenado por un doble es una potencia de 2, más un entero de 52 bits multiplicado por 2 exponente - 52 . Entonces, con el exponente 52 puede almacenar todos los valores desde 2 52 hasta 2 53 - 1. Luego, con el exponente 53, el siguiente número que puede almacenar después de 2 53 es 2 53 + 1 × 2 53 - 52 . Por lo tanto, la pérdida de precisión ocurre primero con 2 53 + 1.


El entero más grande que se puede representar en doble IEEE 754 (64 bits) es el mismo que el valor más grande que el tipo puede representar, ya que ese valor es en sí mismo un número entero.

Esto se representa como 0x7FEFFFFFFFFFFFFF , que se compone de:

  • El signo de bit 0 (positivo) en lugar de 1 (negativo)
  • El exponente máximo 0x7FE (2046 que representa 1023 después de restar el sesgo) en lugar de 0x7FF (2047 que indica un NaN o infinito).
  • La mantisa máxima 0xFFFFFFFFFFFFF que es de 52 bits, todos 1.

En binario, el valor es el implícito 1 seguido de otros 52 unos de la mantisa, luego 971 ceros (1023 - 52 = 971) del exponente.

El valor decimal exacto es:

179769313486231570814527423731704356798070567525844996598917476803157260780028538760589558632766878171540458953514382464234321326889464182768467546703537516986049910576551282076245490090389328944075868508455133942304583236903222948165808559332123348274797826204144723168738177180919299881250404026184124858368

Esto es aproximadamente 1.8 x 10 308 .


Necesitas mirar el tamaño de la mantisa. Un número de punto flotante IEEE 754 de 64 bits (que tiene 52 bits, más 1 implícito) puede representar exactamente números enteros con un valor absoluto menor o igual a 2 ^ 53.


Wikipedia tiene esto que decir en el mismo contexto con un enlace a IEEE 754 :

En un sistema informático típico, un número de punto flotante binario de "doble precisión" (64 bits) tiene un coeficiente de 53 bits (uno de los cuales es implícito), un exponente de 11 bits y un bit de signo.

2 ^ 53 es un poco más de 9 * 10 ^ 15.


DECIMAL_DIG de <float.h> debería dar al menos una aproximación razonable de eso. Como se trata de dígitos decimales, y está realmente almacenado en binario, probablemente puedas almacenar algo un poco más grande sin perder precisión, pero exactamente cuánto es difícil de decir. Supongo que deberías poder resolverlo desde FLT_RADIX y DBL_MANT_DIG , pero no estoy seguro de que confiaría completamente en el resultado.


9007199254740992 (eso es 9,007,199,254,740,992) sin garantías :)

Programa

#include <math.h> #include <stdio.h> int main(void) { double dbl = 0; /* I started with 9007199254000000, a little less than 2^53 */ while (dbl + 1 != dbl) dbl++; printf("%.0f/n", dbl - 1); printf("%.0f/n", dbl); printf("%.0f/n", dbl + 1); return 0; }

Resultado

9007199254740991 9007199254740992 9007199254740992