Formato de coma flotante de doble precisión - Double-precision floating-point format

El formato de punto flotante de doble precisión (a veces llamado FP64 o float64 ) es un formato de número de computadora , que generalmente ocupa 64 bits en la memoria de la computadora; representa un amplio rango dinámico de valores numéricos mediante el uso de un punto de base flotante .

El punto flotante se utiliza para representar valores fraccionarios, o cuando se necesita un rango más amplio que el que proporciona el punto fijo (del mismo ancho de bits), incluso si se paga precisión. Se puede elegir la precisión doble cuando el rango o la precisión de la precisión simple sean insuficientes.

En el estándar IEEE 754-2008 , el formato base 2 de 64 bits se conoce oficialmente como binary64 ; se llamó doble en IEEE 754-1985 . IEEE 754 especifica formatos de punto flotante adicionales, incluida la precisión simple de 32 bits en base 2 y, más recientemente, las representaciones en base 10.

Uno de los primeros lenguajes de programación en proporcionar tipos de datos de punto flotante de precisión simple y doble fue Fortran . Antes de la adopción generalizada de IEEE 754-1985, la representación y las propiedades de los tipos de datos de punto flotante dependían del fabricante y el modelo de la computadora, y de las decisiones tomadas por los implementadores del lenguaje de programación. Por ejemplo, el tipo de datos de doble precisión de GW-BASIC era el formato de coma flotante MBF de 64 bits .

Formato de coma flotante binario de doble precisión IEEE 754: binary64

El punto flotante binario de doble precisión es un formato de uso común en las PC, debido a su rango más amplio que el punto flotante de precisión simple, a pesar de su rendimiento y costo de ancho de banda. Se conoce comúnmente simplemente como doble . El estándar IEEE 754 especifica que un binary64 tiene:

El bit de signo determina el signo del número (incluso cuando este número es cero, que está firmado ).

El campo de exponente es un entero sin signo de 11 bits de 0 a 2047, en forma sesgada : un valor de exponente de 1023 representa el cero real. Los exponentes van de −1022 a +1023 porque los exponentes de −1023 (todos 0) y +1024 (todos 1) están reservados para números especiales.

La precisión de significación de 53 bits proporciona una precisión de 15 a 17 dígitos decimales significativos (2 −53  ≈ 1,11 × 10 −16 ). Si una cadena decimal con un máximo de 15 dígitos significativos se convierte a una representación de doble precisión IEEE 754 y luego se vuelve a convertir a una cadena decimal con el mismo número de dígitos, el resultado final debe coincidir con la cadena original. Si un número de doble precisión IEEE 754 se convierte en una cadena decimal con al menos 17 dígitos significativos y luego se vuelve a convertir a una representación de doble precisión, el resultado final debe coincidir con el número original.

El formato se escribe con el significado que tiene un bit entero implícito de valor 1 (excepto para datos especiales, consulte la codificación del exponente a continuación). Con los 52 bits del significado de la fracción (F) apareciendo en el formato de memoria, la precisión total es por lo tanto de 53 bits (aproximadamente 16 dígitos decimales, 53 log 10 (2) ≈ 15.955). Los bits se distribuyen de la siguiente manera:

Formato de coma flotante doble IEEE 754.svg

El valor real asumido por un dato de precisión doble de 64 bits dado con un exponente sesgado dado y una fracción de 52 bits es

o

Entre 2 52 = 4,503,599,627,370,496 y 2 53 = 9,007,199,254,740,992 los números representables son exactamente los enteros. Para el siguiente rango, de 2 53 a 2 54 , todo se multiplica por 2, por lo que los números representables son los pares, etc. A la inversa, para el rango anterior de 2 51 a 2 52 , el espaciado es 0.5, etc.

El espaciado como fracción de los números en el rango de 2 n a 2 n +1 es 2 n −52 . El error de redondeo relativo máximo cuando se redondea un número al representable más cercano (la máquina épsilon ) es por lo tanto 2 −53 .

El ancho de 11 bits del exponente permite la representación de números entre 10 −308 y 10 308 , con precisión total de 15-17 dígitos decimales. Al comprometer la precisión, la representación subnormal permite valores aún más pequeños, hasta aproximadamente 5 × 10 −324 .

Codificación de exponentes

El exponente de coma flotante binario de doble precisión se codifica utilizando una representación binaria de compensación , siendo la compensación de cero 1023; también conocido como sesgo de exponente en el estándar IEEE 754. Ejemplos de tales representaciones serían:

e = = = 1: 00000000001200116 (exponente más pequeño para números normales )
e = = = 1023: 0111111111123ff16 (compensación cero)
e = = = 1029: 10000000101240516
e = = = 2046: 1111111111027fe16 (exponente más alto)

Los exponentes y tienen un significado especial: 000167ff16

  • 000000000002= se utiliza para representar un cero con signo (si F = 0) y subnormales (si F ≠ 0); y00016
  • 111111111112= se usa para representar (si F = 0) y NaNs (si F ≠ 0),7ff16

donde F es la parte fraccionaria del significando . Todos los patrones de bits son codificaciones válidas.

Excepto por las excepciones anteriores, todo el número de doble precisión se describe mediante:

En el caso de subnormales ( e = 0), el número de doble precisión se describe mediante:

Endianidad

Aunque los omnipresentes procesadores x86 de hoy utilizan almacenamiento little-endian para todos los tipos de datos (enteros, punto flotante), hay una serie de arquitecturas de hardware donde los números de punto flotante se representan en forma de big-endian mientras que los enteros se representan en little- forma endian. Hay procesadores ARM que tienen representación de punto flotante mitad little-endian, mitad big-endian para números de doble precisión: ambas palabras de 32 bits se almacenan en registros de enteros como little-endian, pero el más significativo primero. Debido a que ha habido muchos formatos de punto flotante sin representación estándar de " red " para ellos, el estándar XDR usa big-endian IEEE 754 como su representación. Por lo tanto, puede parecer extraño que el estándar de punto flotante IEEE 754 extendido no especifique endianness. En teoría, esto significa que incluso los datos de punto flotante IEEE estándar escritos por una máquina podrían no ser legibles por otra. Sin embargo, en las computadoras estándar modernas (es decir, que implementan IEEE 754), en la práctica se puede asumir con seguridad que el endianness es el mismo para los números de punto flotante que para los enteros, lo que hace que la conversión sea sencilla independientemente del tipo de datos. ( Sin embargo, los sistemas integrados pequeños que utilizan formatos especiales de punto flotante pueden ser otro asunto).

El punto flotante VAX almacena palabras little-endian de 16 bits en orden big-endian.

Ejemplos de doble precisión

0 01111111111 00000000000000000000000000000000000000000000000000000000 2 ≙ 3FF0 0000 0000 0000 16 ≙ +2 0 × 1 = 1
0 01111111111 0000000000000000000000000000000000000000000000000001 2 ≙ 3FF0 0000 0000 0001 16 ≙ +2 0 × (1 + 2 −52 ) ≈ 1.0000000000000002, el número más pequeño> 1
0 01111111111 00000000000000000000000000000000000000000000000000000010 2 ≙ 3FF0 0000 0000 0002 16 ≙ +2 0 × (1 + 2 −51 ) ≈ 1.0000000000000004
0 10000000000 00000000000000000000000000000000000000000000000000000000 2 ≙ 4000 0000 0000 0000 16 ≙ +2 1 × 1 = 2
1 10000000000 0000000000000000000000000000000000000000000000000000 2 ≙ C000 0000 0000 0000 16 ≙ −2 1 × 1 = −2
0 10000000000 1000000000000000000000000000000000000000000000000000 2 ≙ 4008 0000 0000 0000 16 ≙ +2 1 × 1,1 2 = 11 2 = 3
0 10000000001 00000000000000000000000000000000000000000000000000000000 2 ≙ 4010 0000 0000 0000 16 ≙ +2 2 × 1 = 100 2 = 4
0 10000000001 0100000000000000000000000000000000000000000000000000 2 ≙ 4014 0000 0000 0000 16 ≙ +2 2 × 1.01 2 = 101 2 = 5
0 10000000001 1000000000000000000000000000000000000000000000000000 2 ≙ 4018 0000 0000 0000 16 ≙ +2 2 × 1,1 2 = 110 2 = 6
0 10000000011 01110000000000000000000000000000000000000000000000000000 2 ≙ 4037 0000 0000 0000 16 ≙ +2 4 × 1.0111 2 = 10111 2 = 23
0 01111111000 1000000000000000000000000000000000000000000000000000 2 ≙ 3F88 0000 0000 0000 16 ≙ +2 −7 × 1,1 2 = 0,00000011 2 = 0,01171875 (3/256)
0 00000000000 0000000000000000000000000000000000000000000000000001 2 ≙ 0000 0000 0000 0001 16 ≙ +2 −1022 × 2 −52 = 2 −1074 ≈ 4.9406564584124654 × 10 −324 (Mínimo doble positivo subnormal)
0 00000000000 1111111111111111111111111111111111111111111111111111 2 ≙ 000F FFFF FFFF FFFF 16 ≙ +2 −1022 × ( 1-2 −52 ) ≈ 2.2250738585072009 × 10 −308 (Max. Doble subnormal)
0 00000000001 00000000000000000000000000000000000000000000000000000000 2 ≙ 0010 0000 0000 0000 16 ≙ +2 −1022 × 1 ≈ 2.2250738585072014 × 10 −308 (Mín. Normal positivo doble)
0 11111111110 1111111111111111111111111111111111111111111111111111 2 ≙ 7FEF FFFF FFFF FFFF 16 ≙ +2 1023 × (1 + ( 1-2 −52 )) ≈ 1.7976931348623157 × 10 308 (Max. Doble)
0 00000000000 0000000000000000000000000000000000000000000000000000 2 ≙ 0000 0000 0000 0000 16 ≙ +0
1 00000000000 0000000000000000000000000000000000000000000000000000 2 ≙ 8000 0000 0000 0000 16 ≙ −0
0 11111111111 00000000000000000000000000000000000000000000000000000000 2 ≙ 7FF0 0000 0000 0000 16 ≙ + ∞ (infinito positivo)
1 11111111111 00000000000000000000000000000000000000000000000000000000 2 ≙ FFF0 0000 0000 0000 16 ≙ −∞ (infinito negativo)
0 11111111111 0000000000000000000000000000000000000000000000000001 2 ≙ 7FF0 0000 0000 0001 16 ≙ NaN (sNaN en la mayoría de los procesadores, como x86 y ARM)
0 11111111111 1000000000000000000000000000000000000000000000000001 2 ≙ 7FF8 0000 0000 0001 16 ≙ NaN (qNaN en la mayoría de los procesadores, como x86 y ARM)
0 11111111111 11111111111111111111111111111111111111111111111111 2 ≙ 7FFF FFFF FFFF FFFF 16 ≙ NaN (una codificación alternativa de NaN)
0 01111111101 0101010101010101010101010101010101010101010101010101 2 = 3FD5 5555 5555 5555 16 ≙ 2 -2 × (1 + 2 -2 + 2 -4 + ... + 2 -52 ) ≈ 1 / 3
0 10000000000 1001001000011111101101010100010001000010110100011000 2 = 4009 21FB 5444 2D18 16 ≈ pi

Las codificaciones de qNaN y sNaN no se especifican completamente en IEEE 754 y dependen del procesador. La mayoría de los procesadores, como los procesadores de la familia x86 y la familia ARM , utilizan el bit más significativo del campo significativo para indicar un NaN silencioso; esto es lo que recomienda IEEE 754. Los procesadores PA-RISC usan el bit para indicar una señalización NaN.

Por defecto, 1 / 3 rondas abajo, en lugar de arriba como de precisión simple , debido al número impar de bits en la mantisa.

Con más detalle:

Given the hexadecimal representation 3FD5 5555 5555 555516,
  Sign = 0
  Exponent = 3FD16 = 1021
  Exponent Bias = 1023 (constant value; see above)
  Fraction = 5 5555 5555 555516
  Value = 2(Exponent − Exponent Bias) × 1.Fraction – Note that Fraction must not be converted to decimal here
        = 2−2 × (15 5555 5555 555516 × 2−52)
        = 2−54 × 15 5555 5555 555516
        = 0.333333333333333314829616256247390992939472198486328125
        ≈ 1/3

Velocidad de ejecución con aritmética de doble precisión

El uso de variables de punto flotante de doble precisión y funciones matemáticas (por ejemplo, sin, cos, atan2, log, exp y sqrt) es más lento que trabajar con sus contrapartes de precisión simple. Un área de la informática donde este es un problema particular es el código paralelo que se ejecuta en GPU. Por ejemplo, cuando se usa la plataforma CUDA de NVIDIA , los cálculos con doble precisión toman, según el hardware, aproximadamente de 2 a 32 veces más tiempo en completarse en comparación con los que se realizan con precisión simple .

Limitaciones de precisión en valores enteros

  • Los números enteros de −2 53 a 2 53 (−9,007,199,254,740,992 a 9,007,199,254,740,992) se pueden representar exactamente
  • Enteros entre 2 53 y 2 54 = 18,014,398,509,481,984 redondeados a un múltiplo de 2 (número par)
  • Enteros entre 2 54 y 2 55 = 36,028,797,018,963,968 redondeados a un múltiplo de 4

Implementaciones

Los dobles se implementan en muchos lenguajes de programación de diferentes formas, como las siguientes. En procesadores con solo precisión dinámica, como x86 sin SSE2 (o cuando no se usa SSE2, por motivos de compatibilidad) y con precisión extendida que se usa de forma predeterminada, el software puede tener dificultades para cumplir con algunos requisitos.

C y C ++

C y C ++ ofrecen una amplia variedad de tipos aritméticos . Los estándares no requieren doble precisión (excepto por el anexo opcional F de C99 , que cubre la aritmética IEEE 754), pero en la mayoría de los sistemas, el doubletipo corresponde a doble precisión. Sin embargo, en x86 de 32 bits con precisión extendida de forma predeterminada, algunos compiladores pueden no cumplir con el estándar C o la aritmética puede sufrir un doble redondeo .

Fortran

Fortran proporciona varios tipos enteros y reales, y el tipo de 64 bits real64, accesible a través del módulo intrínseco de Fortran iso_fortran_env, corresponde a doble precisión.

Lisp común

Common Lisp proporciona los tipos SHORT-FLOAT, SINGLE-FLOAT, DOUBLE-FLOAT y LONG-FLOAT. La mayoría de las implementaciones proporcionan SINGLE-FLOATs y DOUBLE-FLOATs con los otros tipos de sinónimos apropiados. Common Lisp proporciona excepciones para detectar subdesbordamientos y desbordamientos de punto flotante, y la excepción de punto flotante inexacto, según IEEE 754. No se describen infinitos ni NaN en el estándar ANSI, sin embargo, varias implementaciones los proporcionan como extensiones.

Java

En Java antes de la versión 1.2, todas las implementaciones tenían que ser compatibles con IEEE 754. La versión 1.2 permitió que las implementaciones brindaran precisión adicional en los cálculos intermedios para plataformas como x87 . Por lo tanto, se introdujo un modificador rigidfp para hacer cumplir los cálculos estrictos de IEEE 754. El punto flotante estricto se ha restaurado en Java 17.

JavaScript

Según lo especificado por el estándar ECMAScript , toda la aritmética en JavaScript se realizará utilizando aritmética de punto flotante de doble precisión.

Ver también

  • IEEE 754 , estándar IEEE para aritmética de punto flotante

notas y referencias