stringtranslate.com

Punto flotante decimal

La aritmética de punto flotante decimal ( DFP ) se refiere tanto a la representación como a las operaciones con números decimales de punto flotante . Trabajar directamente con fracciones decimales (base 10) puede evitar los errores de redondeo que suelen ocurrir al convertir entre fracciones decimales (comunes en datos ingresados ​​por personas, como mediciones o información financiera) y fracciones binarias (base 2).

La ventaja de la representación decimal en coma flotante sobre la representación decimal en coma fija y la representación entera es que admite un rango mucho más amplio de valores. Por ejemplo, mientras que una representación en coma fija que asigna 8 dígitos decimales y 2 lugares decimales puede representar los números 123456.78, 8765.43, 123.00, etc., una representación en coma flotante con 8 dígitos decimales también podría representar 1.2345678, 1234567.8, 0.000012345678, 12345678000000000, etc. Este rango más amplio puede reducir drásticamente la acumulación de errores de redondeo durante cálculos sucesivos; por ejemplo, el algoritmo de suma de Kahan se puede utilizar en coma flotante para sumar muchos números sin acumulación asintótica de errores de redondeo.

Implementaciones

Los primeros usos mecánicos del punto flotante decimal son evidentes en el ábaco , la regla de cálculo , la calculadora Smallwood y algunas otras calculadoras que admiten entradas en notación científica . En el caso de las calculadoras mecánicas, el exponente se suele tratar como información secundaria que se contabiliza por separado.

La computadora IBM 650 admitió un formato de punto flotante decimal de 8 dígitos en 1953. [1] La máquina Wang VS, que de otro modo sería binaria, admitió un formato de punto flotante decimal de 64 bits en 1977. [2] El Motorola 68881 admitió un formato con 17 dígitos de mantisa y 3 de exponente en 1984, y la biblioteca de soporte de punto flotante para el procesador Motorola 68040 proporcionó un formato de almacenamiento de punto flotante decimal compatible de 96 bits en 1990. [2]

Algunos lenguajes de programación tienen implementaciones de aritmética decimal de punto flotante, incluyendo PL/I , .NET , [3] emacs con calc y el módulo decimal de Python . [4] En 1987, el IEEE publicó IEEE 854 , un estándar para computación con punto flotante decimal, que carecía de una especificación sobre cómo se debían codificar los datos de punto flotante para el intercambio con otros sistemas. Esto se abordó posteriormente en IEEE 754-2008 , que estandarizó la codificación de datos de punto flotante decimal, aunque con dos métodos alternativos diferentes.

Los procesadores IBM POWER6 y los más nuevos POWER incluyen DFP en el hardware, al igual que el IBM System z9 [5] (y las máquinas zSeries posteriores). SilMinds ofrece SilAx, un coprocesador DFP vectorial configurable . [6] La norma IEEE 754-2008 lo define con más detalle. Fujitsu también tiene procesadores Sparc de 64 bits con DFP en el hardware. [7] [2]

Codificación IEEE 754-2008

El estándar IEEE 754-2008 define representaciones decimales en coma flotante de 32, 64 y 128 bits. Al igual que los formatos binarios de coma flotante, el número se divide en un signo, un exponente y una mantisa . A diferencia del formato binario de coma flotante, los números no están necesariamente normalizados; los valores con pocos dígitos significativos tienen múltiples representaciones posibles: 1×10 2 = 0,1×10 3 = 0,01×10 4 , etc. Cuando la mantisa es cero, el exponente puede ser cualquier valor.

Los rangos de exponentes se eligieron de modo que el rango disponible para los valores normalizados sea aproximadamente simétrico. Como esto no se puede hacer exactamente con un número par de posibles valores de exponente, se le asignó el valor adicional a Emax.

Se definen dos representaciones diferentes:

Ambas alternativas proporcionan exactamente el mismo rango de valores representables.

Los dos bits más significativos del exponente están limitados al rango de 0 a 2, y los 4 bits más significativos del mantis están limitados al rango de 0 a 9. Las 30 combinaciones posibles están codificadas en un campo de 5 bits, junto con formas especiales para infinito y NaN .

Si los 4 bits más significativos del significando están entre 0 y 7, el valor codificado comienza de la siguiente manera:

s 00mmm xxx El exponente comienza con 00, significando con 0mmms 01mmm xxx El exponente comienza con 01, significado con 0mmms 10mmm xxx El exponente comienza con 10, significando con 0mmm

Si los 4 bits iniciales del mantis son binarios 1000 o 1001 (decimal 8 o 9), el número comienza de la siguiente manera:

s 1100m xxx El exponente comienza con 00, significando con 100ms 1101m xxx El exponente comienza con 01, significando con 100ms 1110m xxx El exponente comienza con 10, significando con 100m

El bit inicial (s en lo anterior) es un bit de signo, y los bits siguientes (xxx en lo anterior) codifican los bits de exponente adicionales y el resto del dígito más significativo, pero los detalles varían dependiendo de la alternativa de codificación utilizada.

Las combinaciones finales se utilizan para infinitos y NaN, y son las mismas para ambas codificaciones alternativas:

s 11110 x ± Infinito (ver Línea de números reales extendida )s 11111 0 NaN silencioso (bit de signo ignorado)s 11111 1 señalización NaN (bit de signo ignorado)

En los últimos casos, se ignoran todos los demás bits de la codificación, por lo que es posible inicializar una matriz en NaN llenándola con un único valor de byte.

Campo de significación de entero binario

Este formato utiliza un mantra binario de 0 a 10 p −1. Por ejemplo, el mantra del decimal 32 puede ser hasta 10 7 −1 = 9 999 999 = 98967F 16 = 1001 1000100101 1001111111 2 . Si bien la codificación puede representar mantras más grandes, son ilegales y el estándar requiere que las implementaciones los traten como 0, si se encuentran en la entrada.

Como se describió anteriormente, la codificación varía dependiendo de si los 4 bits más significativos del significando están en el rango de 0 a 7 (0000 2 a 0111 2 ), o superior (1000 2 o 1001 2 ).

Si los 2 bits después del bit de signo son "00", "01" o "10", entonces el campo de exponente consta de los 8 bits que siguen al bit de signo (los 2 bits mencionados más los 6 bits del "campo de continuación de exponente"), y el significando son los 23 bits restantes, con un bit 0 inicial implícito, que se muestra aquí entre paréntesis:

s 00eeeeee (0)ttt tttttttttt tttttttttt s 01eeeeee (0)ttt tttttttttt tttttttttt s 10eeeeee (0)ttt tttttttttt tttttttttt

Esto incluye números subnormales donde el dígito significativo principal es 0.

Si los 2 bits después del bit de signo son "11", entonces el campo de exponente de 8 bits se desplaza 2 bits hacia la derecha (después del bit de signo y de los bits "11" posteriores), y el significado representado está en los 21 bits restantes. En este caso, hay una secuencia de 3 bits inicial implícita (es decir, no almacenada) "100" en el significado verdadero:

s 1100eeeeee (100)t tttttttttt tttttttttt s 1101eeeeee (100)t tttttttttt tttttttttt s 1110eeeeee (100)t tttttttttt tttttttttt

La secuencia de 2 bits "11" después del bit de signo indica que hay un prefijo implícito "100" de 3 bits para el significando.

Tenga en cuenta que los bits iniciales del campo de mantisa no codifican el dígito decimal más significativo; simplemente son parte de un número binario puro más grande. Por ejemplo, una mantisa de 8 000 000 se codifica como binario 0111 1010000100 1000000000 , con los 4 bits iniciales codificando 7; la primera mantisa que requiere un bit 24 (y por lo tanto la segunda forma de codificación) es 2 23 = 8 388 608 .

En los casos anteriores, el valor representado es:

(−1) signo × 10 exponente −101 × significando

Decimal64 y Decimal128 funcionan de manera análoga, pero con campos de continuación de exponente y significando más grandes. Para Decimal128, la segunda forma de codificación en realidad nunca se usa; el mayor significando válido de 10 34 −1 = 1ED09BEAD87C0378D8E63FFFFFFFF 16 se puede representar en 113 bits.

Campo de significación decimal densamente empaquetado

En esta versión, la mantisa se almacena como una serie de dígitos decimales. El dígito inicial está entre 0 y 9 (3 o 4 bits binarios) y el resto de la mantisa utiliza la codificación decimal densamente empaquetada (DPD).

Los dos primeros bits del exponente y el dígito inicial (3 o 4 bits) de la mantisa se combinan en los cinco bits que siguen al bit de signo. A esto le sigue un campo de continuación de exponente con desplazamiento fijo.

Finalmente, el campo de continuación del significado está formado por 2, 5 u 11 declets de 10 bits , cada uno de los cuales codifica 3 dígitos decimales. [8]

Si los dos primeros bits después del bit de signo son "00", "01" o "10", entonces esos son los bits iniciales del exponente, y los tres bits siguientes se interpretan como el dígito decimal inicial (0 a 7): [9]

 Exponente combinado Significante s 00 TTT (00)eeeeee (0TTT)[tttttttttt][tttttttttt] s 01 TTT (01)eeeeee (0TTT)[tttttttttt][tttttttttt] s 10 TTT (10)eeeeee (0TTT)[tttttttttt][tttttttttt]

Si los dos primeros bits después del bit de signo son "11", entonces los dos segundos bits son los bits iniciales del exponente, y el último bit tiene como prefijo "100" para formar el dígito decimal inicial (8 o 9):

 Exponente combinado Significante s 1100 T (00)eeeeee (100T)[tttttttttt][tttttttttt] s 1101 T (01)eeeeee (100T)[tttttttttt][tttttttttt] s 1110 T (10)eeeeee (100T)[tttttttttt][tttttttttt]

Las dos combinaciones restantes (11110 y 11111) del campo de 5 bits se utilizan para representar ±infinito y NaNs, respectivamente.

Operaciones aritméticas de punto flotante

La regla habitual para realizar operaciones aritméticas de punto flotante es que se calcula el valor matemático exacto [10] y luego se redondea el resultado al valor representable más cercano con la precisión especificada. De hecho, este es el comportamiento exigido para el hardware informático compatible con IEEE, en condiciones normales de redondeo y en ausencia de condiciones excepcionales.

Para facilitar la presentación y la comprensión, en los ejemplos se utilizará una precisión de 7 dígitos. Los principios fundamentales son los mismos en cualquier precisión.

Suma

Un método sencillo para sumar números de punto flotante es representarlos primero con el mismo exponente. En el ejemplo siguiente, el segundo número se desplaza 3 dígitos hacia la derecha. Procedemos con el método de suma habitual:

El siguiente ejemplo es decimal, lo que simplemente significa que la base es 10.

 123456,7 = 1,234567 × 10 5 101,7654 = 1,017654 × 10 2 = 0,001017654 × 10 5

Por eso:

 123456,7 + 101,7654 = (1,234567 × 10 5 ) + (1,017654 × 10 2 ) = (1,234567 × 10 5 ) + (0,001017654 × 10 5 ) = 10 5 × (1,234567 + 0,001017654) = 10 5 × 1,235584654

Esto no es otra cosa que convertir a notación científica . En detalle:

 e=5; s=1,234567 (123456,7)+ e=2; s=1,017654 (101,7654)
 e=5; s=1,234567+ e=5; s=0,001017654 (después del cambio)-------------------- e=5; s=1,235584654 (suma verdadera: 123558,4654)

Este es el resultado real, la suma exacta de los operandos. Se redondeará a 7 dígitos y luego se normalizará si es necesario. El resultado final es:

 e=5; s=1,235585 (suma final: 123558,5)

Tenga en cuenta que los 3 dígitos inferiores del segundo operando (654) se pierden esencialmente. Esto es un error de redondeo . En casos extremos, la suma de dos números distintos de cero puede ser igual a uno de ellos:

 e=5; s=1,234567+ e=−3; s=9,876543
 e=5; s=1,234567+ e=5; s=0,00000009876543 (después del cambio)---------------------- e=5; s=1,23456709876543 (suma verdadera) e=5; s=1,234567 (después del redondeo/normalización)

Otro problema de pérdida de significancia ocurre cuando se restan las aproximaciones a dos números casi iguales. En el siguiente ejemplo, e  = 5; s  = 1,234571 y e  = 5; s  = 1,234567 son aproximaciones a los racionales 123457,1467 y 123456,659.

 e=5; s=1,234571− e=5; s=1,234567---------------- e=5; s=0,000004 e=−1; s=4,000000 (después del redondeo y la normalización)

La diferencia de punto flotante se calcula exactamente porque los números son cercanos: el lema de Sterbenz garantiza esto, incluso en caso de desbordamiento por defecto cuando se admite el desbordamiento por defecto gradual . A pesar de esto, la diferencia de los números originales es e  = −1; s  = 4,877000, que difiere más del 20% de la diferencia e  = −1; s  = 4,000000 de las aproximaciones. En casos extremos, se pueden perder todos los dígitos significativos de precisión. [11] [12] Esta cancelación ilustra el peligro de suponer que todos los dígitos de un resultado calculado son significativos. El tratamiento de las consecuencias de estos errores es un tema del análisis numérico ; consulte también Problemas de precisión.

Multiplicación

Para multiplicar se multiplican los mantis, se suman los exponentes y se redondea y normaliza el resultado.

 e=3; s=4,734612× e=5; s=5,417242----------------------- e=8; s=25,648538980104 (producto verdadero) e=8; s=25,64854 (después del redondeo) e=9; s=2,564854 (después de la normalización)

La división se hace de manera similar, pero es más complicada.

No existen problemas de cancelación o absorción en la multiplicación o división, aunque pueden acumularse pequeños errores a medida que se realizan operaciones repetidamente. En la práctica, la forma en que se llevan a cabo estas operaciones en la lógica digital puede ser bastante compleja.

Véase también

Referencias

  1. ^ Beebe, Nelson HF (22 de agosto de 2017). "Capítulo H. Arquitecturas históricas de punto flotante". Manual de cálculo de funciones matemáticas: programación con la biblioteca de software portátil MathCW (1.ª edición). Salt Lake City, UT, EE. UU.: Springer International Publishing AG . pág. 948. doi :10.1007/978-3-319-64110-2. ISBN. 978-3-319-64109-6. Código LCCN  2017947446. S2CID  30244721.
  2. ^ abc Savard, John JG (2018) [2007]. "El estándar decimal de punto flotante". quadibloc . Archivado desde el original el 2018-07-03 . Consultado el 2018-07-16 .
  3. ^ "Documentación de la API de .NET para System.Decimal". learn.microsoft.com . Consultado el 7 de julio de 2024 .
  4. ^ "Documentación de Python para decimal". docs.python.org . Consultado el 7 de julio de 2024 .
  5. ^ "IBM z9 EC y z9 BC: mayor valor para todos" (PDF) . 306.ibm.com . Consultado el 7 de julio de 2018 .
  6. ^ "IP aritméticas para aplicaciones financieras - SilMinds". Silminds.com .
  7. ^ "Capítulo 4. Formatos de datos". Especificación Sparc64 X/X+ . Nakahara-ku, Kawasaki, Japón. Enero de 2015. pág. 13.{{cite book}}: CS1 maint: location missing publisher (link)
  8. ^ Müller, Jean-Michel; Brisebarre, Nicolás; de Dinechin, Florent; Jeannerod, Claude-Pierre; Lefèvre, Vicente; Melquiond, Guillaume; Revol, Nathalie ; Stehlé, Damián; Torres, Serge (2010). Manual de aritmética de coma flotante (1 ed.). Birkhäuser . doi :10.1007/978-0-8176-4705-6. ISBN 978-0-8176-4704-9. Número de serie LCCN  2009939668.
  9. ^ Especificación de codificación decimal, versión 1.00, de IBM
  10. ^ El hardware de la computadora no necesariamente calcula el valor exacto; simplemente tiene que producir el resultado redondeado equivalente como si hubiera calculado el resultado infinitamente preciso.
  11. ^ Goldberg, David (marzo de 1991). "What Every Computer Scientist Should Know About Floating-Point Arithmetic" (PDF) . Encuestas de computación de la ACM . 23 (1): 5–48. doi :10.1145/103162.103163. S2CID  222008826 . Consultado el 20 de enero de 2016 .([1], [2], [3])
  12. ^ Patente estadounidense 3037701A, Huberto M Sierra, "Medios de control aritmético de punto decimal flotante para calculadora", expedida el 5 de junio de 1962 

Lectura adicional