Articulo de referencia

Aritmética de punto flotante

La Z3 , una de las primeras computadoras electromecánicas programables , incluía aritmética de punto flotante (una réplica se exhibe en el Deutsches Museum de Múnich ). En infor...

La Z3 , una de las primeras computadoras electromecánicas programables , incluía aritmética de punto flotante (una réplica se exhibe en el Deutsches Museum de Múnich ).

En informática , la aritmética de punto flotante ( FP ) es la aritmética aplicada a subconjuntos de números reales formados por una mantisa (una secuencia con signo de un número fijo de dígitos en alguna base ) multiplicada por una potencia entera de esa base. Los números de esta forma se denominan números de punto flotante . [ 1 ] : 3 [ 2 ] : 10

Por ejemplo, el número 2469/200 es un número de coma flotante en base diez con cinco dígitos: 2469/200=12.345=12345significando×10base3exponente{\displaystyle 2469/200=12.345=\!\underbrace {12345} _{\text{significando}}\!\times \!\underbrace {10} _{\text{base}}\!\!\!\!\!\!\!\overbrace {{}^{-3}} ^{\text{exponente}}} Sin embargo, 7716/625 = 12,3456 no es un número de coma flotante en base diez con cinco dígitos ; necesita seis. El número de coma flotante más cercano con solo cinco dígitos es 12,346. Y 1/3 = 0,3333… no es un número de coma flotante en base diez con un número finito de dígitos. En la práctica, la mayoría de los sistemas de coma flotante utilizan la base dos , aunque la base diez ( coma flotante decimal ) también es común.

Las operaciones aritméticas de punto flotante, como la suma y la división, aproximan las operaciones aritméticas de números reales correspondientes redondeando cualquier resultado que no sea un número de punto flotante a un número de punto flotante cercano. [ 1 ] : 22 [ 2 ] : 10 Por ejemplo, en una aritmética de punto flotante con cinco dígitos en base diez, la suma 12.345 + 1.0001 = 13.3451 podría redondearse a 13.345.

El término coma flotante se refiere al hecho de que la raíz del número puede "flotar" en cualquier lugar a la izquierda, a la derecha o entre las cifras significativas del número. Esta posición se indica mediante el exponente, por lo que la coma flotante puede considerarse una forma de notación científica .

Un sistema de punto flotante permite representar, con un número fijo de dígitos, números de órdenes de magnitud muy diferentes , como la distancia en metros entre galaxias o entre protones en un átomo . Por esta razón, la aritmética de punto flotante se utiliza a menudo para manejar números reales muy pequeños y muy grandes que requieren tiempos de procesamiento rápidos. Como resultado de este rango dinámico , los números que se pueden representar no están espaciados uniformemente; la diferencia entre dos números representables consecutivos varía con su exponente. [ 3 ]

Números de coma flotante de precisión simple en una recta numérica : las líneas verdes marcan los valores representables.
Versión ampliada arriba que muestra ambos signos de valores representables

A lo largo de los años, se han utilizado diversas representaciones de punto flotante en las computadoras. En 1985, se estableció el estándar IEEE 754 para la aritmética de punto flotante, y desde la década de 1990, las representaciones más comunes son las definidas por el IEEE.

La velocidad de las operaciones de punto flotante, que se suele medir en términos de FLOPS , es una característica importante de un sistema informático , especialmente para aplicaciones que implican cálculos matemáticos intensivos.

Los números de coma flotante se pueden calcular mediante implementaciones de software (softfloat) o de hardware (hardfloat). Las unidades de coma flotante (FPU, por sus siglas en inglés, coprocesadores matemáticos ) están especialmente diseñadas para realizar operaciones con números de coma flotante y forman parte de la mayoría de los sistemas informáticos. Cuando no se dispone de FPU, se pueden utilizar implementaciones de software.

Descripción general

Números de punto flotante

Una representación numérica especifica alguna forma de codificar un número, generalmente como una cadena de dígitos.

Existen varios mecanismos para representar números mediante secuencias de dígitos. En la notación matemática estándar, la secuencia puede tener cualquier longitud, y la posición del punto decimal se indica colocando un punto (o coma) en dicho punto. Si no se especifica el punto decimal, la secuencia representa implícitamente un número entero , y este se ubicaría fuera de la secuencia, junto al dígito menos significativo. En los sistemas de punto fijo , se especifica una posición en la secuencia para el punto decimal. Así, un sistema de punto fijo podría usar una secuencia de 8 dígitos decimales con el punto decimal en el medio, de modo que "00012345" representaría 0001.2345.

En notación científica , el número dado se escala por una potencia de 10 , de modo que se encuentre dentro de un rango específico, generalmente entre 1 y 10, con el punto decimal apareciendo inmediatamente después del primer dígito. Como potencia de diez, el factor de escala se indica por separado al final del número. Por ejemplo, el período orbital de la luna Io de Júpiter es152.853,5047 segundos, un valor que se representaría en notación científica estándar como1,528535047 × 10 5 segundos.

La representación de punto flotante es similar en concepto a la notación científica. Lógicamente, un número de punto flotante consta de:

  • Una cadena de dígitos con signo (positivo o negativo) de una longitud determinada en una base dada . Esta cadena de dígitos se denomina mantisa o coeficiente . [ nb 1 ] La longitud de la mantisa determina la precisión con la que se pueden representar los números. Se supone que la posición del punto de base siempre está dentro de la mantisa, generalmente justo después o justo antes del dígito más significativo, o a la derecha del dígito más a la derecha (menos significativo). Este artículo sigue generalmente la convención de que el punto de base se coloca justo después del dígito más significativo (más a la izquierda).
  • Un exponente entero con signo (también denominado característica o escala ), [ nb 2 ] que modifica la magnitud del número.

Para obtener el valor del número de punto flotante, la mantisa se multiplica por la base elevada a la potencia del exponente , lo que equivale a desplazar el punto decimal de su posición implícita un número de lugares igual al valor del exponente: a la derecha si el exponente es positivo o a la izquierda si el exponente es negativo.

Utilizando la base 10 (la notación decimal familiar ) como ejemplo, el número152.853,5047 , que tiene diez dígitos decimales de precisión, se representa como la mantisa.1528535047 junto con 5 como exponente. Para determinar el valor real, se coloca un punto decimal después del primer dígito de la mantisa y el resultado se multiplica por 10.5 para dar1,528535047 × 10⁵ , o152.853,5047 . Al almacenar dicho número, no es necesario almacenar la base (10), ya que será la misma para todo el rango de números admitidos y, por lo tanto, se puede inferir.

Simbólicamente, este valor final es: sbpag1×bmi,{\displaystyle {\frac {s}{b^{\,p-1}}}\times b^{e},}

donde s es la mantisa (ignorando cualquier punto decimal implícito), p es la precisión (el número de dígitos en la mantisa), b es la base (en nuestro ejemplo, este es el número diez ) y e es el exponente.

Históricamente, se han utilizado varias bases numéricas para representar números de punto flotante, siendo la base dos ( binaria ) la más común, seguida de la base diez ( punto flotante decimal ) y otras variedades menos comunes, como la base dieciséis ( punto flotante hexadecimal [ 4 ] [ 5 ] [ nb 3 ] ), la base ocho (punto flotante octal [ 1 ] [ 5 ] [ 6 ] [ 4 ] [ nb 4 ] ), la base cuatro (punto flotante cuaternario [ 7 ] [ 5 ] [ nb 5 ] ), la base tres ( punto flotante ternario balanceado [ 1 ] ) e incluso la base 256 [ 5 ] [ nb 6 ] y la base65.536 . [ 8 ] [ nb 7 ]

Un número de punto flotante es un número racional , porque se puede representar como un número entero dividido por otro; por ejemplo1,45 × 10³ es ( 145/100)×1000 o145.000 /100. La base determina las fracciones que se pueden representar; por ejemplo, 1/5 no se puede representar exactamente como un número de punto flotante usando una base binaria, pero 1/5 se puede representar exactamente usando una base decimal (0,2 o2 × 10 −1 ). Sin embargo, 1/3 no puede representarse exactamente ni en binario (0.010101...) ni en decimal (0.333...), pero en base 3 es trivial (0.1 o 1×3 −1 ). Las ocasiones en que ocurren expansiones infinitas dependen de la base y sus factores primos .

La forma en que se almacenan en una computadora la mantisa (incluido su signo) y el exponente depende de la implementación. Los formatos IEEE comunes se describen en detalle más adelante y en otros lugares, pero como ejemplo, en la representación de punto flotante de precisión simple binaria (32 bits),pag=24{\displaystyle p=24}y, por lo tanto, la mantisa es una cadena de 24 bits . Por ejemplo, los primeros 33 bits del número π son: 11001001 00001111 11011010_ 10100010 0.{\displaystyle 11001001\ 00001111\ 1101101{\underline {0}}\ 10100010\ 0.}

En esta expansión binaria, denotemos las posiciones desde 0 (bit más a la izquierda o bit más significativo) hasta 32 (bit más a la derecha). La mantisa de 24 bits se detendrá en la posición  23, que se muestra como el bit subrayado.0 arriba. El siguiente bit, en la posición  24, se llama bit de redondeo . Se utiliza para redondear la aproximación de 33 bits al número de 24 bits más cercano (hay reglas específicas para valores intermedios , lo cual no es el caso aquí). Este bit, que esEn este ejemplo, se suma 1 al número entero formado por los 24 bits más a la izquierda, lo que da como resultado: 11001001 00001111 11011011_.{\displaystyle 11001001\ 00001111\ 1101101{\underline {1}}.}

Cuando esto se almacena en memoria utilizando la codificación IEEE 754, se convierte en la mantisa s . Se supone que la mantisa tiene un punto binario a la derecha del bit más a la izquierda. Por lo tanto, la representación binaria de π se calcula de izquierda a derecha de la siguiente manera: (norte=0pag1poconorte×2norte)×2mi=(1×20+1×21+0×22+0×23++1×223)×211.57079637×23.1415927{\displaystyle {\begin{aligned}&{\biggl (}\sum _{n=0}^{p-1}{\text{bit}}_{n}\times 2^{-n}{\biggr )}\times 2^{e}\\&\qquad {}=\left(1\times 2^{-0}+1\times 2^{-1}+0\times 2^{-2}+0\times 2^{-3}+\cdots +1\times 2^{-23}\right)\times 2^{1}\\[2mu]&\qquad {}\approx 1.57079637\times 2\\[3mu]&\qquad {}\approx 3.1415927\end{aligned}}}

donde p es la precisión (24 en este ejemplo), n es la posición del bit de la mantisa desde la izquierda (comenzando en0 y terminando en23 aquí) y e es el exponente (1 en este ejemplo).

Puede requerirse que el dígito más significativo de la mantisa de un número distinto de cero sea distinto de cero (excepto cuando el exponente correspondiente sea menor que el mínimo). Este proceso se denomina normalización . Para formatos binarios (que utilizan solo los dígitos0 y1 ), este dígito distinto de cero es necesariamente1. Por lo tanto, no necesita estar representado en la memoria, lo que permite que el formato tenga un bit más de precisión. Esta regla se denomina de diversas maneras convención de bit principal , convención de bit implícita , convención de bit oculta , [ 1 ] o convención de bit asumida .

Alternativas a los números de coma flotante

La representación de punto flotante es, con mucho, la forma más común de representar en las computadoras una aproximación a los números reales. Sin embargo, existen alternativas:

  • La representación de punto fijo utiliza operaciones de hardware con números enteros controladas por una implementación de software que sigue una convención específica sobre la ubicación del punto binario o decimal; por ejemplo, a 6 bits o dígitos de la derecha. El hardware para manipular estas representaciones es menos costoso que el de punto flotante y también puede utilizarse para realizar operaciones con números enteros. El punto fijo binario se suele usar en aplicaciones específicas de procesadores integrados que solo admiten aritmética de enteros, mientras que el punto fijo decimal es común en aplicaciones comerciales.
  • Los sistemas de numeración logarítmica (SNL) representan un número real mediante el logaritmo de su valor absoluto y un bit de signo. La distribución de valores es similar a la de punto flotante, pero la curva de relación valor-representación ( es decir , la gráfica de la función logaritmo) es suave (excepto en 0). A diferencia de la aritmética de punto flotante, en un sistema de numeración logarítmica la multiplicación, la división y la exponenciación son sencillas de implementar, pero la suma y la resta son complejas. La aritmética de índice de nivel (LI y SLI) ( simétrica ) de Charles Clenshaw, Frank Olver y Peter Turner es un esquema basado en una representación logarítmica generalizada .
  • Representación de punto flotante cónica , utilizada en formatos Unum , incluido Posit .
  • Algunos números racionales simples ( por ejemplo , 1/3 y 1/10) no se pueden representar con exactitud en coma flotante binaria, independientemente de la precisión. El uso de una base diferente permite representar algunos de ellos ( por ejemplo , 1/10 en coma flotante decimal), pero las posibilidades siguen siendo limitadas. Los programas que realizan aritmética racional representan los números como fracciones con numerador y denominador enteros, y por lo tanto pueden representar cualquier número racional con exactitud. Estos programas generalmente necesitan usar aritmética de " números grandes " para los enteros individuales.
  • La aritmética de intervalos permite representar números como intervalos y obtener límites garantizados en los resultados. Generalmente se basa en otras operaciones aritméticas, en particular la de punto flotante.
  • Los sistemas de álgebra computacional como Mathematica , Maxima y Maple a menudo pueden manejar números irracionales comoπ{\displaystyle \pi }o3{\displaystyle {\sqrt {3}}}de una manera completamente "formal" ( cálculo simbólico ), sin tratar con una codificación específica de la significando. Dicho programa puede evaluar expresiones como "pecado(3π){\displaystyle \sin(3\pi )}"Exactamente, porque está programado para procesar las matemáticas subyacentes directamente, en lugar de utilizar valores aproximados para cada cálculo intermedio."

Historia

Leonardo Torres Quevedo , en 1914, publicó un análisis de punto flotante basado en la máquina analítica .

En 1914, el ingeniero español Leonardo Torres Quevedo publicó Ensayos sobre Automática , [ 9 ] donde diseñó una calculadora electromecánica de propósito especial basada en la máquina analítica de Charles Babbage y describió una forma de almacenar números de punto flotante de manera consistente. Afirmó que los números se almacenarán en formato exponencial comonorte×10metro{\displaystyle n\times 10^{m}}y ofreció tres reglas mediante las cuales se podría implementar la manipulación consistente de números de punto flotante por máquinas. Para Torres, " n siempre será el mismo número de dígitos (por ejemplo, seis), el primer dígito de n será del orden de las décimas, el segundo de las centésimas, etc., y se escribirá cada cantidad en la forma: n ; m ". El formato que propuso muestra la necesidad de una mantisa de tamaño fijo como la que se usa actualmente para datos de punto flotante, fijando la ubicación del punto decimal en la mantisa para que cada representación fuera única, y cómo formatear dichos números especificando una sintaxis que se pudiera ingresar a través de una máquina de escribir , como fue el caso de su Aritmómetro Electromecánico en 1920. [ 10 ] [ 11 ] [ 12 ]

Konrad Zuse , arquitecto del ordenador Z3 , que utiliza una representación binaria de punto flotante de 22 bits.

En 1938, Konrad Zuse de Berlín completó la Z1 , la primera computadora mecánica programable binaria ; [ 13 ] utiliza una representación numérica de punto flotante binario de 24 bits con un exponente con signo de 7 bits, una mantisa de 17 bits (incluido un bit implícito) y un bit de signo. [ 14 ] La Z3 , más confiable y basada en relés , completada en 1941, tiene representaciones para infinitos positivos y negativos; en particular, implementa operaciones definidas con infinito, como la división por infinito , donde1/=0{\displaystyle 1/\infty =0}y se detiene en operaciones no definidas, como0×{\displaystyle 0\times \infty }.

Zuse también propuso, pero no completó, una aritmética de punto flotante cuidadosamente redondeada que incluye±{\displaystyle \pm \infty }y representaciones NaN, anticipándose a las características del estándar IEEE por cuatro décadas. [ 15 ] En contraste, von Neumann desaconsejó el uso de números de punto flotante para la máquina IAS de 1951 , argumentando que la aritmética de punto fijo es preferible. [ 15 ]

La primera computadora comercial con hardware de punto flotante fue la computadora Z4 de Zuse , diseñada entre 1942 y 1945. En 1946, Bell Laboratories presentó el Modelo  V , que implementaba números decimales de punto flotante . [ 16 ]

La Pilot ACE realizaba operaciones aritméticas de punto flotante binario y entró en funcionamiento en 1950 en el Laboratorio Nacional de Física del Reino Unido . Treinta y tres unidades se comercializaron posteriormente bajo el nombre de English Electric DEUCE . Si bien la aritmética se implementaba mediante software, gracias a una frecuencia de reloj de un megahercio, la velocidad de las operaciones de punto flotante y de punto fijo en esta máquina era inicialmente superior a la de muchos ordenadores de la competencia.

En 1954, se lanzó al mercado el IBM 704 , que introdujo el uso de un exponente sesgado . Durante muchas décadas, el hardware de punto flotante solía ser una característica opcional, y los ordenadores que lo incluían se denominaban «ordenadores científicos» o con capacidad de « cálculo científico » (SC) (véase también Extensiones para el Cálculo Científico (XSC)). No fue hasta el lanzamiento del Intel i486 en 1989 que los ordenadores personales de uso general incorporaron la capacidad de punto flotante como característica estándar en su hardware.

La serie UNIVAC 1100/2200 , introducida en 1962, admitía dos representaciones de punto flotante:

  • Precisión simple : 36 bits, organizados como un signo de 1 bit, un exponente de 8 bits y una mantisa de 27 bits.
  • Doble precisión : 72 bits, organizados como un signo de 1 bit, un exponente de 11 bits y una mantisa de 60 bits.

El IBM 7094 , también presentado en 1962, admitía representaciones de precisión simple y doble, pero sin relación con las representaciones del UNIVAC. De hecho, en 1964, IBM introdujo representaciones de punto flotante hexadecimal en sus mainframes System/360 ; estas mismas representaciones siguen estando disponibles para su uso en los sistemas z/Architecture modernos . En 1998, IBM implementó aritmética de punto flotante binaria compatible con IEEE en sus mainframes; en 2005, IBM también añadió aritmética de punto flotante decimal compatible con IEEE.

Inicialmente, las computadoras utilizaban diversas representaciones para los números de coma flotante. La falta de estandarización a nivel de mainframe era un problema constante a principios de la década de 1970 para quienes escribían y mantenían código fuente de alto nivel; estos estándares de coma flotante de los fabricantes diferían en el tamaño de las palabras, las representaciones, el redondeo y la precisión general de las operaciones. La compatibilidad de coma flotante entre múltiples sistemas informáticos requería urgentemente estandarización a principios de la década de 1980, lo que llevó a la creación del estándar IEEE 754 una vez que la palabra de 32 bits (o 64 bits) se generalizó. Este estándar se basó en gran medida en una propuesta de Intel, que estaba diseñando el coprocesador numérico i8087 ; Motorola, que diseñaba el 68000 por la misma época, también aportó información importante.

William Kahan , arquitecto principal del estándar de punto flotante IEEE 754.

En 1989, el matemático e informático William Kahan fue galardonado con el Premio Turing por ser el principal artífice de esta propuesta; contó con la ayuda de su alumno Jerome Coonen y del profesor visitante Harold Stone . [ 17 ]

Entre las innovaciones de la arquitectura x86 (más específicamente de la i8087) se encuentran las siguientes:

  • Una representación de punto flotante especificada con precisión a nivel de cadena de bits, de modo que todos los ordenadores compatibles interpreten los patrones de bits de la misma manera. Esto permite transferir números de punto flotante de forma precisa y eficiente de un ordenador a otro (teniendo en cuenta el orden de bytes ).
  • Un comportamiento especificado con precisión para las operaciones aritméticas: se requiere que el resultado se produzca como si se utilizara aritmética de precisión infinita para generar un valor que luego se redondea según reglas específicas. Esto significa que un programa informático que cumpla con este requisito siempre producirá el mismo resultado ante una entrada determinada, mitigando así la reputación casi mística que la computación de punto flotante había adquirido por su comportamiento hasta ahora aparentemente no determinista.
  • La capacidad de que condiciones excepcionales (desbordamiento, división por cero , etc.) se propaguen a través de un cálculo de manera benigna y luego sean manejadas por el software de forma controlada.

Estas características se heredarían en IEEE 754-1985 (con la excepción de la codificación de valores especiales y excepciones), aunque la precisión interna extendida de x87 implica que requiere un redondeo explícito de los resultados exactos directamente a la precisión de destino para que coincidan con los resultados estándar de IEEE 754. [ 18 ] Sin embargo, el comportamiento puede no ser el mismo que un redondeo al formato de destino debido a un posible rango de exponente más amplio del formato extendido.

Rango de números de coma flotante

Un número de punto flotante se compone de dos componentes de punto fijo , cuyo rango depende exclusivamente del número de bits o dígitos en su representación. Mientras que los componentes dependen linealmente de su rango, el rango del número de punto flotante depende linealmente del rango de la mantisa y exponencialmente del rango del componente exponente, lo que le confiere un rango considerablemente mayor.

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 (incluido 1 bit implícito), un exponente de 11 bits y 1 bit de signo. Dado que 2 10 = 1024, el rango completo de los números de punto flotante normales positivos en este formato va desde 2 −1022  2  ×  10 −308 hasta aproximadamente 2 1024  2  ×  10 308 .

El número de números de punto flotante normales en un sistema ( B , P , L , U ) donde

  • B es la base del sistema,
  • P es la precisión de la mantisa (en base B ),
  • L es el exponente más pequeño del sistema,
  • U es el exponente más grande del sistema,

es2(B1)(BPAG1)(UL+1){\displaystyle 2\left(B-1\right)\left(B^{P-1}\right)\left(U-L+1\right)}, o2(B1)(BPAG1)(UL+1)+1{\displaystyle 2\left(B-1\right)\left(B^{P-1}\right)\left(U-L+1\right)+1}considerando el valor 0.

Existe un número de punto flotante normal positivo más pequeño,

Nivel de desbordamiento inferior = UFL =BL{\displaystyle B^{L}},

que tiene un 1 como dígito principal y 0 para los dígitos restantes de la mantisa, y el valor más pequeño posible para el exponente.

Existe un número de punto flotante más grande,

Nivel de desbordamiento = OFL =(1BPAG)(BU+1){\displaystyle \left(1-B^{-P}\right)\left(B^{U+1}\right)},

que tiene B − 1 como valor para cada dígito de la mantisa y el mayor valor posible para el exponente.

Además, existen valores representables estrictamente entre −UFL y UFL. Es decir, ceros positivos y negativos , así como números subnormales .

IEEE 754: coma flotante en computadoras modernas

En 1985, el IEEE estandarizó la representación informática de números de coma flotante binarios en la norma IEEE 754 (también conocida como IEC 60559). Esta primera norma es adoptada por casi todas las máquinas modernas y fue revisada en 2008. Los mainframes de IBM admiten el formato de coma flotante hexadecimal propio de IBM y el formato de coma flotante decimal IEEE 754-2008 , además del formato binario IEEE 754. La serie Cray T90 contaba con una versión IEEE, pero el SV1 aún utiliza el formato de coma flotante de Cray.

El estándar contempla muchos formatos estrechamente relacionados, que difieren solo en algunos detalles. Cinco de estos formatos se denominan formatos básicos , y otros se denominan formatos de precisión extendida y formato de precisión extensible . Tres formatos se utilizan especialmente en hardware y lenguajes informáticos:

  • Precisión simple (binary32), que se usa habitualmente para representar el tipo "float" en la familia de lenguajes C. Este es un formato binario que ocupa 32 bits (4 bytes) y su mantisa tiene una precisión de 24 bits (aproximadamente 7 dígitos decimales).
  • Doble precisión (binary64), que se usa habitualmente para representar el tipo "double" en la familia de lenguajes C. Este es un formato binario que ocupa 64 bits (8 bytes) y su mantisa tiene una precisión de 53 bits (aproximadamente 16 dígitos decimales).
  • Doble extendido , también llamado ambiguamente formato de "precisión extendida". Este es un formato binario que ocupa al menos 79 bits (80 si no se usa la regla de bits ocultos/implícitos) y su mantisa tiene una precisión de al menos 64 bits (aproximadamente 19 dígitos decimales). Los estándares C99 y C11 de la familia de lenguajes C, en su anexo F ("Aritmética de punto flotante IEC 60559"), recomiendan que dicho formato extendido se proporcione como " long double ". [ 19 ] Un formato que satisface los requisitos mínimos (precisión de mantisa de 64 bits, exponente de 15 bits, por lo que cabe en 80 bits) lo proporciona la arquitectura x86 . A menudo en dichos procesadores, este formato se puede usar con "long double", aunque la precisión extendida no está disponible con MSVC. [ 20 ] Para fines de alineación , muchas herramientas almacenan este valor de 80 bits en un espacio de 96 bits o 128 bits. [ 21 ] [ 22 ] En otros procesadores, "long double" puede representar un formato más grande, como precisión cuádruple, [ 23 ] o simplemente precisión doble, si no está disponible ninguna forma de precisión extendida. [ 24 ]

Generalmente, aumentar la precisión de la representación de punto flotante reduce la cantidad de error de redondeo acumulado causado por cálculos intermedios. [ 25 ] Otros formatos IEEE incluyen:

Cualquier número entero con valor absoluto menor que 2²⁴ puede representarse con exactitud en formato de precisión simple, y cualquier número entero con valor absoluto menor que 2⁵³ puede representarse con exactitud en formato de doble precisión. Además, se puede representar un amplio rango de potencias de 2 de dicho número. Estas propiedades se utilizan a veces para datos puramente enteros, para obtener enteros de 53 bits en plataformas que admiten coma flotante de doble precisión pero solo enteros de 32 bits.

El estándar especifica algunos valores especiales y su representación: infinito positivo ( +∞ ), infinito negativo ( −∞ ), un cero negativo (−0) distinto del cero ordinario ("positivo") y valores "no numéricos" ( NaN ).

La comparación de números de coma flotante, según la definición del estándar IEEE, difiere ligeramente de la comparación habitual de enteros. Los ceros negativos y positivos se comparan como iguales, y cada NaN se compara como distinto de cualquier otro valor, incluido él mismo. Todos los números de coma flotante finitos son estrictamente menores que +∞ y estrictamente mayores que −∞ , y se ordenan de la misma manera que sus valores (en el conjunto de los números reales).

Representación interna

Los números de punto flotante se suelen empaquetar en un dato informático como el bit de signo, el campo del exponente y un campo para la mantisa, de izquierda a derecha. Para los formatos binarios IEEE 754 (básico y extendido) que cuentan con implementaciones de hardware existentes, se distribuyen de la siguiente manera:

Si bien el exponente puede ser positivo o negativo, en formatos binarios se almacena como un número sin signo con un sesgo fijo. Los valores de 0 en este campo están reservados para los ceros y los números subnormales ; los valores de 1 están reservados para los infinitos y los NaN. El rango del exponente para números normales es [−126, 127] para precisión simple, [−1022, 1023] para precisión doble o [−16382, 16383] para precisión cuádruple. Los números normales excluyen los valores subnormales, los ceros, los infinitos y los NaN.

En los formatos de intercambio binario IEEE, el bit principal de una mantisa normalizada no se almacena en el dato informático, ya que siempre es 1. Se le denomina bit "oculto" o "implícito". Por este motivo, el formato de precisión simple tiene una mantisa con 24 bits de precisión, el formato de doble precisión tiene 53, el formato cuádruple tiene 113 y el formato óctuple tiene 237.

Por ejemplo, se mostró anteriormente que π, redondeado a 24 bits de precisión, tiene:

  • signo = 0  ; e = 1  ; s = 110010010000111111011011 (incluido el bit oculto)

La suma del sesgo exponencial (127) y el exponente (1) es 128, por lo que esto se representa en el formato de precisión simple como

  • 0 10000000 10010010000111111011011 (excluyendo el bit oculto) = 40490FDB [ 28 ] como un número hexadecimal .

Un ejemplo de diseño para punto flotante de 32 bits es

y la disposición de 64 bits ("doble") es similar.

Otros formatos de punto flotante destacables

Además de los formatos estándar IEEE 754 , ampliamente utilizados, en ciertos ámbitos específicos se utilizan o se han utilizado otros formatos de punto flotante.

  • El formato binario de Microsoft (MBF) se desarrolló para los productos del lenguaje Microsoft BASIC, incluyendo el primer producto de Microsoft, Altair BASIC (1975), TRS-80 LEVEL II , MBASIC de CP/M , BASICA de IBM PC 5150 , GW-BASIC de MS-DOS y QuickBASIC antes de la versión 4.00. QuickBASIC versiones 4.00 y 4.50 cambiaron al formato IEEE 754-1985, pero pueden volver al formato MBF usando la opción de comando /MBF. MBF fue diseñado y desarrollado en un Intel 8080 simulado por Monte Davidoff , compañero de habitación de Bill Gates , durante la primavera de 1975 para el MITS Altair 8800. La versión inicial de julio de 1975 admitía un formato de precisión simple (32 bits) debido al costo de la memoria de 4 kilobytes del MITS Altair 8800 . En diciembre de 1975, la versión de 8 kilobytes agregó un formato de doble precisión (64 bits). Se adoptó un formato variante de precisión simple (40 bits) para otras CPU, en particular el MOS 6502 ( Apple II , Commodore PET , Atari ), Motorola 6800 (MITS Altair 680) y Motorola 6809 ( TRS-80 Color Computer ). Todos los productos de lenguaje de Microsoft desde 1975 hasta 1987 utilizaron el formato binario de Microsoft hasta que Microsoft adoptó el formato estándar IEEE 754 en todos sus productos desde 1988 hasta sus versiones actuales. MBF consta del formato MBF de precisión simple (32 bits, "BASIC de 6 dígitos"), [ 29 ] [ 30 ] el formato MBF de precisión extendida (40 bits, " BASIC de 9 dígitos"), [ 30 ] y el formato MBF de doble precisión (64 bits); [ 29 ] [ 31 ] cada uno de ellos está representado con un exponente de 8 bits, seguido de un bit de signo, seguido de una mantisa de 23, 31 y 55 bits respectivamente.
  • El formato bfloat16 requiere la misma cantidad de memoria (16 bits) que el formato de precisión media IEEE 754 , pero asigna 8 bits al exponente en lugar de 5, lo que proporciona el mismo rango que un número de precisión simple IEEE 754. La desventaja es una precisión reducida, ya que el campo de la mantisa final se reduce de 10 a 7 bits. Este formato se utiliza principalmente en el entrenamiento de modelos de aprendizaje automático , donde el rango es más valioso que la precisión. Muchos aceleradores de aprendizaje automático ofrecen soporte de hardware para este formato.
  • El formato TensorFloat-32 [ 32 ] combina los 8 bits del exponente de bfloat16 con los 10 bits del campo de mantisa final de los formatos de precisión media, lo que resulta en un tamaño de 19 bits. Este formato fue introducido por Nvidia , que proporciona soporte de hardware para él en los Tensor Cores de sus GPU basadas en la arquitectura Nvidia Ampere. La desventaja de este formato es su tamaño, que no es una potencia de 2. Sin embargo, según Nvidia, este formato solo debe usarse internamente por el hardware para acelerar los cálculos, mientras que las entradas y salidas deben almacenarse en el formato IEEE 754 de precisión simple de 32 bits. [ 32 ]
  • Las GPU con arquitectura Hopper y CDNA 3 proporcionan dos formatos FP8: uno con el mismo rango numérico que la precisión media (E5M2) y otro con mayor precisión, pero menor rango (E4M3). [ 33 ] [ 34 ]
  • La arquitectura de GPU Blackwell y CDNA 4 incluye soporte para los formatos FP6 (E3M2 y E2M3) y FP4 (E2M1). FP4 es el formato de punto flotante más pequeño que permite todos los principios IEEE 754 (ver minifloat ).

Números representables, conversión y redondeo.

Por su naturaleza, todos los números expresados ​​en formato de punto flotante son números racionales con una expansión finita en la base correspondiente (por ejemplo, una expansión decimal finita en base 10 o una expansión binaria finita en base 2). Los números irracionales, como π o2{\textstyle {\sqrt {2}}}Los números racionales no terminantes deben aproximarse. El número de dígitos (o bits) de precisión también limita el conjunto de números racionales que pueden representarse exactamente. Por ejemplo, el número decimal 123456789 no puede representarse exactamente si solo se dispone de ocho dígitos decimales de precisión (se redondearía a uno de los dos valores representables intermedios, 12345678  ×  10 1 o 12345679  ×  10 1 ), lo mismo se aplica a los dígitos no terminantes (. 5 se redondearía a .55555555 o .55555556).

Cuando un número se representa en un formato (como una cadena de caracteres) que no es una representación nativa de punto flotante compatible con una implementación informática, se requiere una conversión antes de poder utilizarlo en dicha implementación. Si el número se puede representar con exactitud en formato de punto flotante, la conversión es exacta. Si no existe una representación exacta, la conversión requiere elegir qué número de punto flotante utilizar para representar el valor original. La representación elegida tendrá un valor diferente al original, y este valor ajustado se denomina valor redondeado .

Que un número racional tenga o no una expansión finita depende de la base. Por ejemplo, en base 10, el número 1/2 tiene una expansión finita (0.5), mientras que el número 1/3 no la tiene (0.333...). En base 2, solo los racionales con denominadores que son potencias de 2 (como 1/2 o 3/16) tienen una expansión finita. Cualquier racional con un denominador que tenga un factor primo distinto de 2 tendrá una expansión binaria infinita. Esto significa que los números que parecen cortos y exactos cuando se escriben en formato decimal pueden necesitar aproximarse al convertirlos a punto flotante binario. Por ejemplo, el número decimal 0.1 no se puede representar en punto flotante binario con ninguna precisión finita; la representación binaria exacta tendría una secuencia "1100" que continúa indefinidamente.

mi = −4; s = 1100110011001100110011001100110011...,

donde, como antes, s es la mantisa y e es el exponente.

Cuando se redondea a 24 bits, esto se convierte en

mi = −4; s = 110011001100110011001101,

que en realidad es 0,100000001490116119384765625 en decimal.

Como ejemplo adicional, el número real π , representado en binario como una secuencia infinita de bits es

11.0010010000111111011010101000100010000101101000110000100011010011...

pero es

11.0010010000111111011011

cuando se aproxima mediante redondeo a una precisión de 24 bits.

En punto flotante binario de precisión simple, esto se representa como s  =  1.10010010000111111011011 con e  =  1. Esto tiene un valor decimal de

3.141592 7410125732421875,

mientras que una aproximación más precisa del verdadero valor de π es

3.14159265358979323846264338327950 ...

El resultado del redondeo difiere del valor real en aproximadamente 0,03 partes por millón y coincide con la representación decimal de π en los primeros 7 dígitos. La diferencia es el error de discretización y está limitada por el épsilon de la máquina .

La diferencia aritmética entre dos números de coma flotante representables consecutivos que tienen el mismo exponente se denomina unidad en la última posición (ULP). Por ejemplo, si no hay ningún número representable entre los números representables 1.45A70C22 16 y 1.45A70C24 16 , la ULP es 2 × 16 − 8 , o 2 − 31. Para números con una parte exponencial de base 2 igual a 0, es decir, números con un valor absoluto mayor o igual a 1 pero menor que 2, una ULP es exactamente 2 − 23 o aproximadamente 10 − 7 en precisión simple, y exactamente 2 − 53 o aproximadamente 10 − 16 en precisión doble. El comportamiento obligatorio del hardware compatible con IEEE es que el resultado esté dentro de la mitad de una ULP.

Modos de redondeo

El redondeo se utiliza cuando el resultado exacto de una operación de punto flotante (o una conversión a formato de punto flotante) necesitaría más dígitos que los dígitos de la mantisa. IEEE 754 requiere un redondeo correcto : es decir, el resultado redondeado es como si se hubiera utilizado aritmética de precisión infinita para calcular el valor y luego redondearlo (aunque en la implementación solo se necesitan tres bits adicionales para garantizar esto). Hay varios esquemas de redondeo diferentes (o modos de redondeo ). Históricamente, el truncamiento era el enfoque típico. Desde la introducción de IEEE 754, el método predeterminado ( redondear al más cercano, empates al par , a veces llamado Redondeo Bancario) es el más utilizado. Este método redondea el resultado ideal (de precisión infinita) de una operación aritmética al valor representable más cercano y da esa representación como resultado. [ nb 8 ] En caso de empate, se elige el valor que haría que la mantisa terminara en un dígito par. El estándar IEEE 754 exige que se aplique el mismo redondeo a todas las operaciones algebraicas fundamentales, incluidas la raíz cuadrada y las conversiones, cuando el resultado es numérico (distinto de NaN). Esto significa que los resultados de las operaciones IEEE 754 se determinan completamente en todos los bits del resultado, excepto en la representación de los NaN. (Las funciones de la biblioteca, como el coseno y el logaritmo, no son obligatorias).

También existen opciones de redondeo alternativas. La norma IEEE 754 especifica los siguientes modos de redondeo:

  • redondeo al más cercano, donde los empates se redondean al dígito par más cercano en la posición requerida (el modo predeterminado y, con mucho, el más común).
  • redondear al número entero más cercano; en caso de empate, redondear alejándose de cero (opcional para números de coma flotante binarios y comúnmente utilizado en decimales).
  • redondeo hacia arriba (hacia +∞; los resultados negativos se redondean hacia cero)
  • redondear hacia abajo (hacia −∞; los resultados negativos se redondean alejándose de cero).
  • redondeo hacia cero (truncamiento; es similar al comportamiento común de las conversiones de flotante a entero, que convierten −3,9 a −3 y 3,9 a 3).

Los modos alternativos son útiles cuando se debe limitar la cantidad de error introducido. Las aplicaciones que requieren un error limitado son la aritmética de punto flotante de precisión múltiple y la aritmética de intervalos . Los modos de redondeo alternativos también son útiles para diagnosticar la inestabilidad numérica: si los resultados de una subrutina varían sustancialmente entre el redondeo a + y − infinito, es probable que sea numéricamente inestable y esté afectada por el error de redondeo. [ 35 ]

Conversión de binario a decimal con el mínimo número de dígitos.

Convertir un número binario de punto flotante de doble precisión a una cadena decimal es una operación común, pero un algoritmo que produjera resultados precisos y concisos no apareció impreso hasta 1990, con Dragon4 de Steele y White. Algunas de las mejoras desde entonces incluyen:

  • dtoa.c de David M. Gay , una implementación práctica de código abierto de muchas ideas de Dragon4. [ 36 ]
  • Grisu3, con una aceleración de 4 × ya que elimina el uso de números grandes . Debe usarse con un método alternativo, ya que falla en aproximadamente el 0,5 % de los casos. [ 37 ]
  • Errol3, un algoritmo que siempre tiene éxito, similar a Grisu3, pero más lento. Aparentemente no es tan bueno como un Grisu de terminación temprana con reserva. [ 38 ]
  • Ryū, un algoritmo que siempre tiene éxito, es más rápido y sencillo que Grisu3. [ 39 ]
  • Schubfach, un algoritmo que siempre tiene éxito y que se basa en una idea similar a la de Ryū, se desarrolló casi simultáneamente y de forma independiente. [ 40 ] Tiene un mejor rendimiento que Ryū y Grisu3 en ciertos benchmarks. [ 41 ]

Muchos entornos de ejecución de lenguajes modernos utilizan Grisu3 con una alternativa Dragon4. [ 42 ]

Conversión de decimal a binario

El problema de convertir una cadena decimal en una representación binaria de punto flotante es complejo, y no se encontró un analizador preciso hasta el trabajo de Clinger de 1990 (implementado en dtoa.c). [ 36 ] Asimismo, se ha avanzado en la dirección de un análisis más rápido. [ 43 ]

Operaciones de punto flotante

Para facilitar la presentación y la comprensión, en los ejemplos se utilizará la base decimal con precisión de 7 dígitos, como en el formato IEEE 754 decimal32 . Los principios fundamentales son los mismos independientemente de la base o precisión, salvo que la normalización es opcional (no afecta al valor numérico del resultado). Aquí, s representa la mantisa y e el exponente.

Suma y resta

Un método sencillo para sumar números de coma flotante consiste en representarlos primero con el mismo exponente. En el ejemplo siguiente, el segundo número (con el exponente menor) se desplaza tres dígitos a la derecha y, a continuación, se procede con el método de suma habitual:

 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) = (1,234567 + 0,001017654) × 10^5 = 1,235584654 × 10^5

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 desplazamiento) -------------------- e=5; s=1,235584654 (suma real: 123558,4654)

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

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

Los tres dígitos menos significativos del segundo operando (654) se pierden prácticamente por completo. Esto se debe a 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 desplazamiento) ---------------------- e=5; s=1,23456709876543 (suma real) e=5; s=1,234567 (después del redondeo y la normalización)

En los ejemplos conceptuales anteriores, parecería que el sumador necesitaría proporcionar una gran cantidad de dígitos adicionales para garantizar un redondeo correcto; sin embargo, para la suma o resta binaria, utilizando técnicas de implementación cuidadosas, solo se necesita llevar un bit de guarda , un bit de redondeo y un bit de retención adicional más allá de la precisión de los operandos. [ 18 ] [ 44 ] : 218–220

Otro problema de pérdida de significado ocurre cuando se restan 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 números 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 están cerca; el lema de Sterbenz lo garantiza, incluso en caso de subdesbordamiento cuando se admite el subdesbordamiento 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. [ 18 ] [ 45 ] Esta cancelación ilustra el peligro de asumir que todos los dígitos de un resultado calculado son significativos. Abordar las consecuencias de estos errores es un tema en el análisis numérico ; véase también Problemas de precisión .

Multiplicación y división

Para multiplicar, se multiplican las mantisas mientras se suman los exponentes, y el resultado se redondea y normaliza.

 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)

De manera similar, la división se realiza restando el exponente del divisor al exponente del dividendo y dividiendo la mantisa del dividendo entre la mantisa del divisor.

No existen problemas de cancelación o absorción con la multiplicación o la división, aunque pueden acumularse pequeños errores a medida que las operaciones se realizan sucesivamente. [ 18 ] En la práctica, la forma en que se llevan a cabo estas operaciones en lógica digital puede ser bastante compleja (véase el algoritmo de multiplicación de Booth y el algoritmo de división ). [ nb 9 ]

sintaxis literal

Los literales para números de punto flotante dependen del lenguaje. Normalmente usan eo Epara denotar la notación científica . El lenguaje de programación C y el estándar IEEE 754 también definen una sintaxis literal hexadecimal con un exponente de base 2 en lugar de 10. En lenguajes como C , cuando se omite el exponente decimal, se necesita un punto decimal para diferenciarlos de los enteros. Otros lenguajes no tienen un tipo entero (como JavaScript ), o permiten la sobrecarga de tipos numéricos (como Haskell ). En estos casos, las cadenas de dígitos como 123también pueden ser literales de punto flotante.

Ejemplos de literales de punto flotante son:

  • 99.9
  • -5000.12
  • 6.02e23
  • -3e-45
  • 0x1.fffffep+127en C y IEEE 754

Cómo tratar casos excepcionales

Los cálculos de punto flotante en una computadora pueden presentar tres tipos de problemas:

  • Una operación puede no estar definida matemáticamente, como ∞/∞ o la división por cero .
  • Una operación puede ser legal en principio, pero no estar respaldada por el formato específico; por ejemplo, calcular la raíz cuadrada de −1 o el seno inverso de 2 (ambos dan como resultado números complejos ).
  • Una operación puede ser legal en principio, pero el resultado puede ser imposible de representar en el formato especificado, porque el exponente es demasiado grande o demasiado pequeño para codificarlo en el campo correspondiente. Este fenómeno se denomina desbordamiento (exponente demasiado grande), subdesbordamiento (exponente demasiado pequeño) o desnormalización (pérdida de precisión).

Antes del estándar IEEE, tales condiciones generalmente provocaban la terminación del programa o activaban algún tipo de trampa que el programador podía interceptar. El funcionamiento dependía del sistema, lo que significaba que los programas de punto flotante no eran portables .

El término "excepción", tal como se usa en IEEE 754, es un término general que significa una condición excepcional, que no necesariamente es un error, y es un uso diferente al que se define típicamente en lenguajes de programación como C++ o Java, en los que una " excepción " es un flujo de control alternativo, más cercano a lo que se denomina una "trampa" en la terminología de IEEE 754. Sin embargo, en dichos lenguajes, aún se puede lanzar una excepción de flujo de control como esta ArithmeticException.

Aquí se analiza el método predeterminado requerido para el manejo de excepciones según IEEE 754 (no se discuten el manejo opcional de excepciones ni otros modos de manejo alternativo de excepciones de IEEE 754). Las excepciones aritméticas deben registrarse (por defecto) en bits de estado "persistentes". Que sean "persistentes" significa que no se restablecen con la siguiente operación (aritmética), sino que permanecen activadas hasta que se restablezcan explícitamente. El uso de indicadores "persistentes" permite retrasar la comprobación de condiciones excepcionales hasta después de una expresión o subrutina de punto flotante completa: sin ellos, las condiciones excepcionales que no podrían ignorarse de otro modo requerirían una comprobación explícita inmediatamente después de cada operación de punto flotante. Por defecto, una operación siempre devuelve un resultado según la especificación sin interrumpir el cálculo. Por ejemplo, 1/0 devuelve +∞, al tiempo que activa el bit de indicador de división por cero (este valor predeterminado de ∞ está diseñado para devolver a menudo un resultado finito cuando se utiliza en operaciones posteriores y, por lo tanto, puede ignorarse de forma segura).

Sin embargo, el estándar original IEEE 754 no recomendaba operaciones para manejar dichos conjuntos de bits de indicadores de excepción aritmética. Por lo tanto, aunque estos se implementaron en hardware, inicialmente las implementaciones de lenguajes de programación generalmente no proporcionaban un medio para acceder a ellos (aparte del ensamblador). Con el tiempo, algunos estándares de lenguajes de programación (por ejemplo, C99 /C11 y Fortran) se han actualizado para especificar métodos para acceder y cambiar los bits de indicadores de estado. La versión de 2008 del estándar IEEE 754 ahora especifica algunas operaciones para acceder y manejar los bits de indicadores aritméticos. El modelo de programación se basa en un único hilo de ejecución y su uso por múltiples hilos debe manejarse mediante un medio externo al estándar (por ejemplo, C11 especifica que los indicadores tienen almacenamiento local de hilo ).

La norma IEEE 754 especifica cinco excepciones aritméticas que deben registrarse en los indicadores de estado ("bits persistentes"):

  • inexacto , se establece si el valor redondeado (y devuelto) es diferente del resultado matemáticamente exacto de la operación.
  • underflow , se establece si el valor redondeado es pequeño (como se especifica en IEEE 754) e inexacto (o tal vez limitado si tiene pérdida de desnormalización, según la versión de 1985 de IEEE 754), devolviendo un valor subnormal que incluye los ceros.
  • Desbordamiento : se activa si el valor absoluto del valor redondeado es demasiado grande para ser representado. Se devuelve un valor infinito o un valor finito máximo, según el redondeo utilizado.
  • división por cero , se establece si el resultado es infinito dados operandos finitos, devolviendo un infinito, ya sea +∞ o −∞.
  • inválido , se establece si no se puede devolver un resultado finito o infinito, por ejemplo, sqrt(−1) o 0/0, devolviendo un NaN silencioso.
Figura 1: resistencias en paralelo, con resistencia totalRtot{\displaystyle R_{tot}}

El valor de retorno predeterminado para cada una de las excepciones está diseñado para dar el resultado correcto en la mayoría de los casos, de modo que las excepciones se pueden ignorar en la mayoría de los códigos. inexact devuelve un resultado redondeado correctamente, y underflow devuelve un valor menor o igual al número normal positivo más pequeño en magnitud y casi siempre se puede ignorar. [ 46 ] divide-by-zero devuelve infinito exactamente, que normalmente dividirá un número finito y, por lo tanto, dará cero, o bien dará una excepción no válida posteriormente si no, por lo que también se puede ignorar normalmente. Por ejemplo, la resistencia efectiva de n resistencias en paralelo (véase la figura 1) viene dada porRnene=1/(1/R1+1/R2++1/Rnorte){\displaystyle R_{\text{total}}=1/(1/R_{1}+1/R_{2}+\cdots +1/R_{n})}. Si se produce un cortocircuito conR1{\displaystyle R_{1}}establecido a 0,1/R1{\displaystyle 1/R_{1}}devolverá +infinito, lo que dará un resultado final.Rtot{\displaystyle R_{tot}}de 0, como se esperaba [ 47 ] (véase el ejemplo de fracción continua de la justificación del diseño IEEE 754 para otro ejemplo).

Las excepciones de desbordamiento e inválidas generalmente no se pueden ignorar, pero no necesariamente representan errores: por ejemplo, una rutina de búsqueda de raíz , como parte de su operación normal, puede evaluar una función pasada como argumento con valores fuera de su dominio, devolviendo NaN y una bandera de excepción inválida que debe ignorarse hasta encontrar un punto de inicio útil. [ 46 ]

Problemas de precisión

El hecho de que los números de coma flotante no puedan representar con exactitud todos los números reales, y que las operaciones de coma flotante no puedan representar con exactitud las operaciones aritméticas verdaderas, da lugar a muchas situaciones sorprendentes. Esto se debe a la precisión finita con la que, por lo general, los ordenadores representan los números.

Por ejemplo, los números decimales 0.1 y 0.01 no se pueden representar exactamente como números binarios de punto flotante. En el formato binario IEEE 754 de 32 bits con su mantisa de 24 bits, el resultado de intentar elevar al cuadrado la aproximación a 0.1 no es ni 0.01 ni el número representable más cercano a él. El número decimal 0.1 se representa en binario como e  =  −4 ; s  =  110011001100110011001101 , que es

0,100000001490116119384765625 exactamente.

Elevar al cuadrado este número da como resultado

0,010000000298023226097399174250313080847263336181640625 exactamente.

Elevarlo al cuadrado con redondeo a la precisión de 24 bits da como resultado

0,010000000707805156707763671875 exactamente.

Pero el número representable más cercano a 0,01 es

0,009999999776482582092285156250 exactamente.

Además, la no representabilidad de π (y π/2) implica que un intento de calcular tan(π/2) no dará como resultado infinito, ni siquiera se desbordará en los formatos de punto flotante habituales (suponiendo una implementación precisa de tan). Simplemente no es posible que el hardware estándar de punto flotante intente calcular tan(π/2), porque π/2 no se puede representar con exactitud. Este cálculo en C:

// Suficientes dígitos para asegurarnos de obtener la aproximación correcta. const double pi = 3.1415926535897932384626433832795 ; double z = tan ( pi / 2.0 );

dará un resultado de 16331239353195370.0. En precisión simple (usando la tanffunción), el resultado será −22877332.0.

Del mismo modo, un intento de calcular sin( π ) no dará como resultado cero. El resultado será (aproximadamente) 0,1225 × 10⁻¹⁵ en precisión doble, o −0,8742 × 10⁻⁷ en precisión simple. [ nb 10 ]

Si bien la suma y la multiplicación de punto flotante son conmutativas ( a + b = b + a y a × b = b × a ), no son necesariamente asociativas . Es decir, ( a + b ) + c no es necesariamente igual a a + ( b + c ) . Usando aritmética decimal con mantisa de 7 dígitos:

a = 1234,567, b = 45,67834, c = 0,0004
(a + b) + c: 1234.567 (a) + 45.67834 (b) ____________ 1280.24534 se redondea a 1280.245
 1280,245 (a + b) + 0,0004 (c) ____________ 1280.2454 se redondea a 1280.245 ← (a + b) + c
a + (b + c): 45.67834 (b) + 0,0004 (c) ____________ 45.67874
 1234.567 (a) + 45,67874 (b + c) ____________ 1280.24574 se redondea a 1280.246 ← a + (b + c)

Tampoco son necesariamente distributivos . Es decir, ( a + b ) × c puede no ser lo mismo que a × c + b × c :

1234,567 × 3,333333 = 4115,223 1,234567 × 3,333333 = 4,115223 4115,223 + 4,115223 = 4119,338 pero 1234,567 + 1,234567 = 1235,802 1235,802 × 3,333333 = 4119,340

Además de la pérdida de significado, la incapacidad de representar con exactitud números como π y 0,1, y otras pequeñas imprecisiones, pueden ocurrir los siguientes fenómenos:

  • Cancelación : la resta de operandos casi iguales puede causar una pérdida extrema de precisión. [ 48 ] [ 45 ] Cuando restamos dos números casi iguales, ponemos a cero los dígitos más significativos, quedándonos solo con los dígitos insignificantes y más erróneos. [ 1 ] : 124 Por ejemplo, al determinar la derivada de una función se utiliza la siguiente fórmula: Q(h)=F(a+h)F(a)h.{\displaystyle Q(h)={\frac {f(a+h)-f(a)}{h}}.} Intuitivamente, se desearía un valor de h muy cercano a cero; sin embargo, al usar operaciones de punto flotante, el número más pequeño no proporcionará la mejor aproximación de una derivada. A medida que h disminuye, la diferencia entre f ( a + h ) y f ( a ) también disminuye, lo que anula los dígitos más significativos y menos erróneos y hace que los dígitos más erróneos adquieran mayor importancia. Como resultado, el valor más pequeño posible de h dará una aproximación más errónea de una derivada que un valor algo mayor. Este es quizás el problema de precisión más común y grave.
  • Las conversiones a números enteros no son intuitivas: convertir (63,0/9,0) a entero da como resultado 7, pero convertir (0,63/0,09) puede dar como resultado 6. Esto se debe a que las conversiones generalmente truncan en lugar de redondear. Las funciones de piso y techo pueden producir resultados que difieren en uno del valor esperado intuitivamente.
  • Rango de exponentes limitado: los resultados pueden desbordarse, dando como resultado infinito, o subdesbordarse, dando como resultado un número subnormal o cero. En estos casos, se perderá precisión.
  • Comprobar si una división es segura es problemático: verificar que el divisor no sea cero no garantiza que la división no se desborde.
  • La comprobación de igualdad es problemática. Dos secuencias computacionales que son matemáticamente iguales bien pueden producir valores de punto flotante diferentes. [ 49 ]

Incidentes

Precisión de la máquina y análisis de errores inversos

La precisión de la máquina es una magnitud que caracteriza la exactitud de un sistema de punto flotante y se utiliza en el análisis de errores inversos de algoritmos de punto flotante. También se conoce como redondeo unitario o épsilon de máquina . Generalmente se denota como E mach y su valor depende del redondeo específico que se utilice.

Con redondeo a cero, mimach=B1PAG,{\displaystyle \mathrm {E} _{\text{mach}}=B^{1-P},\,} mientras que redondear al más cercano, mimach=12B1PAG,{\displaystyle \mathrm {E} _{\text{mach}}={\tfrac {1}{2}}B^{1-P},} donde B es la base del sistema y P es la precisión de la mantisa (en base B ).

Esto es importante ya que limita el error relativo al representar cualquier número real distinto de cero x dentro del rango normalizado de un sistema de punto flotante: |Florida(incógnita)incógnitaincógnita|mimach.{\displaystyle \left|{\frac {\operatorname {fl} (x)-x}{x}}\right|\leq \mathrm {E} _{\text{mach}}.}

El análisis de errores hacia atrás, cuya teoría fue desarrollada y popularizada por James H. Wilkinson , puede utilizarse para establecer que un algoritmo que implementa una función numérica es numéricamente estable. [ 52 ] El enfoque básico consiste en demostrar que, si bien el resultado calculado, debido a errores de redondeo, no será exactamente correcto, es la solución exacta a un problema cercano con datos de entrada ligeramente perturbados. Si la perturbación requerida es pequeña, del orden de la incertidumbre en los datos de entrada, entonces los resultados son, en cierto sentido, tan precisos como los datos "merecen". El algoritmo se define entonces como estable hacia atrás . La estabilidad es una medida de la sensibilidad a los errores de redondeo de un procedimiento numérico dado; por el contrario, el número de condición de una función para un problema dado indica la sensibilidad inherente de la función a pequeñas perturbaciones en su entrada y es independiente de la implementación utilizada para resolver el problema. [ 53 ]

Como ejemplo trivial, consideremos una expresión simple que da el producto escalar de vectores (de longitud dos).incógnita{\displaystyle x}yy{\displaystyle y}, entonces Florida(incógnitay)=Florida(Florida(incógnita1y1)+Florida(incógnita2y2)), dónde Florida() indica aritmética de punto flotante correctamente redondeada=Florida((incógnita1y1)(1+δ1)+(incógnita2y2)(1+δ2)), dónde δnortemimach, desde arriba=((incógnita1y1)(1+δ1)+(incógnita2y2)(1+δ2))(1+δ3)=(incógnita1y1)(1+δ1)(1+δ3)+(incógnita2y2)(1+δ2)(1+δ3),{\displaystyle {\begin{aligned}\operatorname {fl} (x\cdot y)&=\operatorname {fl} {\big (}\operatorname {fl} (x_{1}\cdot y_{1})+\operatorname {fl} (x_{2}\cdot y_{2}){\big )},&&{\text{ where }}\operatorname {fl} (){\text{ indicates correctly rounded floating-point arithmetic}}\\&=\operatorname {fl} {\big (}(x_{1}\cdot y_{1})(1+\delta _{1})+(x_{2}\cdot y_{2})(1+\delta _{2}){\big )},&&{\text{ where }}\delta _{n}\leq \mathrm {E} _{\text{mach}},{\text{ from above}}\\&={\big (}(x_{1}\cdot y_{1})(1+\delta _{1})+(x_{2}\cdot y_{2})(1+\delta _{2}){\big )}(1+\delta _{3})\\&=(x_{1}\cdot y_{1})(1+\delta _{1})(1+\delta _{3})+(x_{2}\cdot y_{2})(1+\delta _{2})(1+\delta _{3}),\end{aligned}}} y entonces Florida(incógnitay)=incógnita^y^,{\displaystyle \operatorname {fl} (x\cdot y)={\hat {x}}\cdot {\hat {y}},}

dónde

incógnita^1=incógnita1(1+δ1);incógnita^2=incógnita2(1+δ2);y^1=y1(1+δ3);y^2=y2(1+δ3),{\displaystyle {\begin{aligned}{\hat {x}}_{1}&=x_{1}(1+\delta _{1});&{\hat {x}}_{2}&=x_{2}(1+\delta _{2});\\{\hat {y}}_{1}&=y_{1}(1+\delta _{3});&{\hat {y}}_{2}&=y_{2}(1+\delta _{3}),\\\end{aligned}}}

dónde

δnortemimach{\displaystyle \delta _{n}\leq \mathrm {E} _{\text{mach}}}

Por definición, que es la suma de dos datos de entrada ligeramente perturbados (del orden de E mach ), y por lo tanto es retroestable. Para ejemplos más realistas en álgebra lineal numérica , véase Higham 2002 [ 54 ] y otras referencias a continuación.

Minimizar el efecto de los problemas de precisión

Aunque las operaciones aritméticas individuales de IEEE 754 tienen una precisión garantizada de medio ULP , las fórmulas más complejas pueden sufrir errores mayores por diversas razones. La pérdida de precisión puede ser sustancial si un problema o sus datos están mal condicionados , lo que significa que el resultado correcto es hipersensible a pequeñas perturbaciones en sus datos. Sin embargo, incluso las funciones bien condicionadas pueden sufrir una gran pérdida de precisión si se utiliza un algoritmo numéricamente inestable para esos datos: formulaciones aparentemente equivalentes de expresiones en un lenguaje de programación pueden diferir notablemente en su estabilidad numérica. Un enfoque para eliminar el riesgo de dicha pérdida de precisión es el diseño y análisis de algoritmos numéricamente estables, que es un objetivo de la rama de las matemáticas conocida como análisis numérico . Otro enfoque que puede proteger contra el riesgo de inestabilidades numéricas es el cálculo de valores intermedios (de referencia) en un algoritmo con una precisión mayor que la que requiere el resultado final, [ 55 ] lo que puede eliminar, o reducir en órdenes de magnitud, [ 56 ] dicho riesgo: la precisión cuádruple y la precisión extendida IEEE 754 están diseñadas para este propósito cuando se calcula con doble precisión. [ 57 ] [ nb 11 ]

Por ejemplo, el siguiente algoritmo es una implementación directa para calcular la función.F(incógnita)=incógnita1exp(incógnita1)1{\displaystyle f(x)={\frac {x-1}{\exp(x-1)-1}}}, que está bien acondicionado enincógnita=1{\displaystyle x=1}. [ nb 12 ] Sin embargo, se puede demostrar que es numéricamente inestable y pierde hasta la mitad de los dígitos significativos que lleva la aritmética cuando se calcula cerca de 1.0. [ 58 ]

#include <math.h>double f ( double x ) { double y = x - 1.0 ; double z = exp ( y ); if ( z != 1.0 ) { z = y / ( z - 1.0 ); } return z ; }

Un análisis numérico del algoritmo revela que si z = y / (z - 1.0);se realiza el siguiente cambio no obvio en la línea:

z = log ( z ) / ( z - 1.0 );

Entonces el algoritmo se vuelve numéricamente estable y puede calcular con precisión doble completa. [ 58 ]

Para mantener las propiedades de programas numéricamente estables cuidadosamente diseñados, se requiere un manejo minucioso por parte del compilador . Ciertas optimizaciones que los compiladores pueden realizar (por ejemplo, reordenar operaciones) pueden ir en contra de los objetivos de un software bien comportado. Existe cierta controversia sobre las deficiencias de los compiladores y los diseños de lenguajes en este ámbito: C99 es un ejemplo de un lenguaje donde dichas optimizaciones se especifican cuidadosamente para mantener la precisión numérica. Consulte las referencias externas al final de este artículo.

Un tratamiento detallado de las técnicas para escribir software de punto flotante de alta calidad está fuera del alcance de este artículo, y se remite al lector a [ 54 ] [ 59 ] y a las demás referencias al final de este artículo. Kahan sugiere varias reglas generales que pueden disminuir sustancialmente en órdenes de magnitud [ 59 ] el riesgo de anomalías numéricas, además de, o en lugar de, un análisis numérico más cuidadoso. Estas incluyen: como se mencionó anteriormente, calcular todas las expresiones y resultados intermedios con la mayor precisión admitida por el hardware (una regla general común es llevar el doble de la precisión del resultado deseado, es decir, calcular en doble precisión para un resultado final de precisión simple, o en doble precisión extendida o cuádruple para resultados de hasta doble precisión [ 60 ] ); y redondeando los datos de entrada y los resultados a la precisión requerida y admitida por los datos de entrada (llevar una precisión excesiva en el resultado final más allá de la requerida y admitida por los datos de entrada puede ser engañoso, aumenta el costo de almacenamiento y disminuye la velocidad, y los bits adicionales pueden afectar la convergencia de los procedimientos numéricos: [ 61 ] en particular, la primera forma del ejemplo iterativo que se presenta a continuación converge correctamente cuando se utiliza esta regla general). A continuación se describen brevemente varios problemas y técnicas adicionales.

Como las fracciones decimales a menudo no se pueden representar exactamente en punto flotante binario, dicha aritmética es más útil cuando simplemente se usa para medir cantidades del mundo real en una amplia gama de escalas (como el período orbital de una luna alrededor de Saturno o la masa de un protón ), y más útil cuando se espera que modele las interacciones de cantidades expresadas como cadenas decimales que se espera que sean exactas. [ 56 ] [ 59 ] Un ejemplo de este último caso son los cálculos financieros. Por esta razón, el software financiero tiende a no usar una representación numérica de punto flotante binario. [ 62 ] El tipo de datos "decimal" de los lenguajes de programación C# y Python , y los formatos decimales del estándar IEEE 754-2008 , están diseñados para evitar los problemas de las representaciones de punto flotante binario cuando se aplican a valores decimales exactos ingresados ​​por humanos, y hacen que la aritmética siempre se comporte como se espera cuando los números se imprimen en decimal.

Las expectativas derivadas de las matemáticas pueden no cumplirse en el campo de la computación de punto flotante. Por ejemplo, se sabe que(incógnita+y)(incógnitay)=incógnita2y2{\displaystyle (x+y)(x-y)=x^{2}-y^{2}\,}y quepecado2θ+porque2θ=1{\displaystyle \sin ^{2}{\theta }+\cos ^{2}{\theta }=1\,}Sin embargo, no se puede confiar en estos datos cuando las cantidades involucradas son el resultado de cálculos de punto flotante.

El uso de la prueba de igualdad ( if (x==y) ...) requiere cuidado al tratar con números de punto flotante. Incluso expresiones simples como 0.6 / 0.2 - 3 == 0no serán verdaderas en la mayoría de las computadoras [ 63 ] (en IEEE 754, la doble precisión, por ejemplo, 0.6 / 0.2 - 3es aproximadamente igual a−4.440 892 098 500 63 × 10 −16 ). En consecuencia, tales pruebas a veces se reemplazan con comparaciones "difusas" ( if (abs(x-y) < epsilon) ..., donde épsilon es suficientemente pequeño y adaptado a la aplicación, como 1.0E−13). La conveniencia de hacer esto varía mucho y puede requerir análisis numérico para acotar épsilon. [ 54 ] Los valores derivados de la representación de datos primarios y sus comparaciones deben realizarse en una precisión más amplia y extendida para minimizar el riesgo de tales inconsistencias debido a errores de redondeo. [ 59 ] A menudo es mejor organizar el código de tal manera que tales pruebas sean innecesarias. Por ejemplo, en geometría computacional , las pruebas exactas de si un punto está fuera o sobre una línea o plano definido por otros puntos se pueden realizar utilizando precisión adaptativa o métodos aritméticos exactos. [ 64 ]

Los pequeños errores en la aritmética de punto flotante pueden aumentar cuando los algoritmos matemáticos realizan operaciones un número enorme de veces. Algunos ejemplos son la inversión de matrices , el cálculo de vectores propios y la resolución de ecuaciones diferenciales. Estos algoritmos deben diseñarse con sumo cuidado, utilizando enfoques numéricos como el refinamiento iterativo , para que funcionen correctamente. [ 65 ]

La suma de un vector de valores de punto flotante es un algoritmo básico en la computación científica , por lo que es fundamental comprender cuándo puede producirse una pérdida de significancia. Por ejemplo, si se suma una cantidad muy grande de números, los sumandos individuales son muy pequeños en comparación con la suma. Esto puede provocar una pérdida de significancia. Una suma típica sería entonces algo como:

3253.671 + 3.141276 ----------- 3256.812

Los tres dígitos menos significativos de los sumandos se pierden efectivamente. Supongamos, por ejemplo, que se necesita sumar muchos números, todos aproximadamente iguales a 3. Después de sumar 1000 de ellos, la suma acumulada es de aproximadamente 3000; los dígitos perdidos no se recuperan. El algoritmo de suma de Kahan puede utilizarse para reducir los errores. [ 54 ]

El error de redondeo puede afectar la convergencia y la precisión de los procedimientos numéricos iterativos. Por ejemplo, Arquímedes aproximó π calculando los perímetros de polígonos que inscribían y circunscribían un círculo, comenzando con hexágonos y duplicando sucesivamente el número de lados. Como se mencionó anteriormente, los cálculos pueden reorganizarse de una manera matemáticamente equivalente pero menos propensa a errores ( análisis numérico ). Dos formas de la fórmula de recurrencia para el polígono circunscrito son:

  • t0=13{\textstyle t_{0}={\frac {1}{\sqrt {3}}}}
  • Primera forma:ti+1=ti2+11ti{\textstyle t_{i+1}={\frac {{\sqrt {t_{i}^{2}+1}}-1}{t_{i}}}}
  • Segunda forma:ti+1=titi2+1+1{\textstyle t_{i+1}={\frac {t_{i}}{{\sqrt {t_{i}^{2}+1}}+1}}}
  • π6×2i×ti{\displaystyle \pi \sim 6\times 2^{i}\times t_{i}}, convergiendo comoi{\displaystyle i\rightarrow \infty }

Aquí se muestra un cálculo utilizando la aritmética "double" de IEEE (una mantisa con 53 bits de precisión):

i 6 × 2 i × t i , primera forma 6 × 2 i × t i , segunda forma --------------------------------------------------------- 0 3 .4641016151377543863 3 .4641016151377543863 1 3 .2153903091734710173 3 .2153903091734723496 2 3.1 596599420974940120 3.1 596599420975006733 3 3.14 60862151314012979 3.14 60862151314352708 4 3.14 27145996453136334 3.14 27145996453689225 5 3.141 8730499801259536 3.141 8730499798241950 6 3.141 6627470548084133 3.141 6627470568494473 7 3.141 6101765997805905 3.141 6101766046906629 8 3.14159 70343230776862 3.14159 70343215275928 9 3.14159 37488171150615 3.14159 37487713536668 10 3.141592 9278733740748 3.141592 9273850979885 11 3.141592 7256228504127 3.141592 7220386148377 12 3.1415926 717412858693 3.1415926 707019992125 13 3.1415926 189011456060 3.14159265 78678454728 14 3.1415926 717412858693 3.14159265 46593073709 15 3.14159 19358822321783 3.141592653 8571730119 16 3.1415926 717412858693 3.141592653 6566394222 17 3.1415 810075796233302 3.141592653 6065061913 18 3.1415926 717412858693 3.1415926535 939728836 19 3.141 4061547378810956 3.1415926535 908393901 20 3.14 05434924008406305 3.1415926535 900560168 21 3.14 00068646912273617 3.141592653589 8608396 22 3.1 349453756585929919 3.141592653589 8122118 23 3.14 00068646912273617 3.14159265358979 95552 24 3 .2245152435345525443 3.14159265358979 68907 25 3.14159265358979 62246 26 3.14159265358979 62246 27 3.14159265358979 62246 28 3.14159265358979 62246 El valor real es 3.14159265358979323846264338327...

Si bien las dos formas de la fórmula de recurrencia son claramente equivalentes desde el punto de vista matemático, [ nb 13 ] la primera resta 1 a un número extremadamente cercano a 1, lo que conlleva una pérdida cada vez más problemática de dígitos significativos . A medida que la recurrencia se aplica repetidamente, la precisión mejora inicialmente, pero luego se deteriora. Nunca supera los 8 dígitos, a pesar de que la aritmética de 53 bits debería ser capaz de alcanzar unos 16 dígitos de precisión. Cuando se utiliza la segunda forma de la recurrencia, el valor converge a 15 dígitos de precisión.

Optimización de "matemáticas rápidas"

La mencionada falta de asociatividad de las operaciones de punto flotante en general significa que los compiladores no pueden reordenar expresiones aritméticas con la misma eficacia que con la aritmética de enteros y de punto fijo, lo que representa un obstáculo para optimizaciones como la eliminación de subexpresiones comunes y la autovectorización . [ 66 ] La opción "matemáticas rápidas" en muchos compiladores (ICC, GCC, Clang, MSVC...) activa la reasociación junto con suposiciones inseguras como la ausencia de NaN y números infinitos en IEEE 754. Algunos compiladores también ofrecen opciones más granulares para activar únicamente la reasociación o para marcar regiones específicas del código para una optimización más agresiva. [ 67 ] En cualquier caso, el programador está expuesto a muchos de los problemas de precisión mencionados anteriormente para la parte del programa que utiliza matemáticas "rápidas". [ 68 ]

En algunos compiladores (GCC y Clang [cuando hay una instalación de GCC presente]), activar las operaciones matemáticas "rápidas" puede provocar que el programa desactive los números de coma flotante subnormales al inicio, lo que afecta al comportamiento de coma flotante no solo del código generado, sino también de cualquier programa que utilice dicho código como biblioteca . Esto se solucionó en GCC 13. [ 69 ]

En la mayoría de los compiladores de Fortran , según lo permite el estándar ISO/IEC 1539-1:2004, la reasociación es la predeterminada, y la configuración "protect parens" (también activada por defecto) evita en gran medida los problemas. Esta configuración impide que el compilador reasocie más allá de los límites de los paréntesis. [ 70 ] El compilador Intel Fortran es una excepción notable. [ 71 ]

Un problema común en las matemáticas "rápidas" es que las subexpresiones pueden no optimizarse de forma idéntica en todos los casos, lo que genera diferencias inesperadas. Una interpretación del problema es que las matemáticas "rápidas", tal como se implementan actualmente, tienen una semántica mal definida. Un intento de formalizar las optimizaciones de matemáticas "rápidas" se observa en Icing , un compilador verificado. [ 72 ]

Véase también

Notas

  1. Algunos autores también denominan mantisa a la significando de un número de coma flotante, término que no debe confundirse con la mantisa de un logaritmo . Otros utilizan términos algo imprecisos como coeficiente o argumento . El uso del término fracción por parte de algunos autores también puede resultar engañoso. El término característica (como lo utiliza, por ejemplo, el CDC ) es ambiguo, ya que históricamente también se empleaba para especificar algún tipo de exponente de números de coma flotante.
  2. El exponente de un número de punto flotante a veces también se denomina escala . El término característica (para exponente sesgado , sesgo del exponente o representación de exceso n ) es ambiguo, ya que históricamente también se utilizaba para especificar la mantisa de los números de punto flotante.
  3. La aritmética de punto flotante hexadecimal (base 16) se utiliza en los sistemas IBM System 360 (1964) y 370 (1970), así como en varias máquinas IBM más recientes, en los mainframes RCA Spectra 70 (1964), Siemens 4004 (1965), 7.700 (1974), 7.800, 7.500 (1977) y sus sucesores, los mainframes Unidata serie 7.000, el Manchester MU5 (1972), los ordenadores HEP (1982) y en familias de mainframes compatibles con 360/370 fabricadas por Fujitsu, Amdahl y Hitachi. También se utilizaen el Illinois ILLIAC III (1966), Data General Eclipse S/200 (aprox. 1974), Gould Powernode 9080 (década de 1980), Interdata 8/32 (década de 1970), los SEL Systems 85 y 86 , así como en el SDS Sigma 5 (1967), 7 (1966) y Xerox Sigma 9 (1970).
  4. La aritmética de punto flotante octal (base 8) se utiliza en lascomputadoras Ferranti Atlas (1962), Burroughs B5500 (1964), Burroughs B5700 (1971), Burroughs B6700 (1971)y Burroughs B7700 (1972)
  5. La aritmética de punto flotante cuaternaria (base 4) se utiliza en lacomputadora Illinois ILLIAC II (1962). También se utiliza en los sistemas de levantamiento de campo de alta resolución DFS IV y V del Sistema Digital de Campo.
  6. La aritmética de punto flotante en base 256 se utiliza en lacomputadora R1 del Instituto Rice (desde 1958).
  7. En la computadora MANIAC II (1956)se utiliza aritmética de punto flotante en base 65536
  8. El hardware informático no necesariamente calcula el valor exacto; simplemente tiene que producir el resultado redondeado equivalente como si hubiera calculado el resultado infinitamente preciso.
  9. La enorme complejidad de los algoritmos de división modernos provocó en su momento un famoso error. Una versión temprana del chip Intel Pentium incluía una instrucción de división que, en raras ocasiones, arrojaba resultados ligeramente incorrectos. Muchos ordenadores se distribuyeron antes de que se descubriera el error. Hasta que se sustituyeron los ordenadores defectuosos, se desarrollaron versiones modificadas de los compiladores para evitar los casos que fallaban. Véase el error FDIV del Pentium .
  10. Pero un intento de cálculo deporque(π){\displaystyle \cos(\pi )}rendimientos1{\displaystyle -1}exactamente. Dado que la derivada es casi cero cercaπ{\displaystyle \pi }, el efecto de la imprecisión en el argumento es mucho menor que el espaciado de los números de punto flotante alrededor1{\displaystyle -1}y el resultado redondeado es exacto.
  11. William Kahan señala: "Salvo en situaciones extremadamente raras, la aritmética de gran precisión generalmente atenúa los riesgos debidos al redondeo a un costo mucho menor que el de un analista de errores competente."
  12. El desarrollo de Taylor de esta función demuestra que está bien condicionada cerca deincógnita=1{\displaystyle x=1}:F(incógnita)=1incógnita12+(incógnita1)212(incógnita1)4720+(incógnita1)630240(incógnita1)81209600+{\displaystyle f(x)=1-{\frac {x-1}{2}}+{\frac {(x-1)^{2}}{12}}-{\frac {(x-1)^{4}}{720}}+{\frac {(x-1)^{6}}{30240}}-{\frac {(x-1)^{8}}{1209600}}+\cdots }para|incógnita1|<π{\displaystyle |x-1|<\pi }.
  13. La equivalencia de ambas expresiones se puede verificar algebraicamente observando que el denominador de la fracción en la segunda expresión es el conjugado del numerador de la primera. Al multiplicar el numerador y el denominador de la primera expresión por este conjugado, se obtiene la segunda expresión.

Referencias

  1. 1 2 3 4 5 6 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. LCCN 2009939668 . 
  2. 1 2 Sterbenz, Pat H. (1974). Floating-Point Computation . Englewood Cliffs, NJ, Estados Unidos: Prentice-Hall. ISBN 0-13-322495-3.
  3. Smith, Steven W. (1997). «Capítulo 28, Punto fijo versus punto flotante» . Guía del científico e ingeniero para el procesamiento digital de señales . California Technical Pub. pág. 514. ISBN  978-0-9660176-3-2. Consultado el 31 de diciembre de 2012 .
  4. ^ Zehendner , Eberhard (verano de 2008). "Rechnerarithmetik: Fest- und Gleitkommasysteme" (PDF) (guión de la conferencia) (en alemán). Universidad Friedrich Schiller de Jena . pag. 2. Archivado (PDF) desde el original el 2018-08-07 . Consultado el 7 de agosto de 2018 . (Nota: Esta referencia indica erróneamente que la base de punto flotante del MANIAC II es 256, cuando en realidad es 65536).
  5. 1 2 3 4 Beebe, Nelson HF (22 de agosto de 2017). «Capítulo H. Arquitecturas históricas de punto flotante». The Mathematical-Function Computation Handbook - Programming Using the MathCW Portable Software Library (1.ª ed.). Salt Lake City, UT, EE. UU.: Springer International Publishing AG . p. 948. doi : 10.1007/978-3-319-64110-2 . ISBN   978-3-319-64109-6. LCCN 2017947446 . S2CID 30244721 .  
  6. Savard, John JG (2018) [2007], "El estándar de punto flotante decimal" , quadibloc , archivado del original el 3 de julio de 2018 , recuperado el 16 de julio de 2018
  7. Parkinson, Roger (2000-12-07). "Capítulo 2 - Sistemas de levantamiento digital de sitios de alta resolución - Capítulo 2.1 - Sistemas de registro digital de campo" . Levantamientos de sitios de alta resolución (1.ª ed.). CRC Press . pág. 24. ISBN   978-0-20318604-6. Consultado el 18 de agosto de 2019. […] Sistemas como el [Sistema de Campo Digital] DFS IV y DFS V eran sistemas de punto flotante cuaternarios y utilizaban pasos de ganancia de 12  dB. […](256 páginas)
  8. Lazarus, Roger B. (30-01-1957) [01-10-1956]. "MANIAC II" (PDF) . Los Alamos, NM, EE. UU.: Laboratorio Científico de Los Alamos de la Universidad de California. pág. 14. LA-2083. Archivado (PDF) del original el 07-08-2018 . Recuperado el 07-08-2018 . […] la base flotante del Maniac, que es 2¹⁶ = 65.536. […] La gran base del Maniac permite un aumento considerable en la velocidad de la aritmética de punto flotante. Aunque una base tan grande implica la posibilidad de hasta 15 ceros iniciales, el gran tamaño de palabra de 48 bits garantiza una significancia adecuada. […] 
  9. Torres Quevedo, Leonardo. Automática: Complemento de la Teoría de las Máquinas, (pdf) , págs. 575–583, Revista de Obras Públicas, 19 de noviembre de 1914.
  10. Ronald T. Kneusel. Números y computadoras , Springer, págs. 84–85, 2017. ISBN 978-3319505084
  11. Randell 1982 , págs. 6, 11–13.
  12. Randell, Brian. Computadoras digitales, historia de sus orígenes, (pdf) , pág. 545, Computadoras digitales: orígenes, Enciclopedia de la informática, enero de 2003.
  13. Rojas, Raúl (abril-junio de 1997). "El legado de Konrad Zuse: la arquitectura de la Z1 y la Z3" (PDF) . IEEE Annals of the History of Computing . 19 (2): 5–16 . doi : 10.1109/85.586067 . Archivado (PDF) del original el 3 de julio de 2022. Consultado el 3 de julio de 2022 .(12 páginas)
  14. Rojas, Raúl (2014-06-07). "The Z1: Architecture and Algorithms of Konrad Zuse's First Computer". arXiv : 1406.1886 [ cs.AR ].
  15. 1 2 Kahan, William Morton (15 de julio de 1997). "El efecto pernicioso de los lenguajes informáticos y los benchmarks sobre las matemáticas aplicadas, la física y la química. Conferencia John von Neumann" (PDF) . pág. 3. Archivado (PDF) del original el 5 de septiembre de 2008. 
  16. Randell, Brian , ed. (1982) [1973]. Los orígenes de las computadoras digitales: artículos seleccionados (3.ª ed.). Berlín; Nueva York: Springer-Verlag . pág. 244. ISBN   978-3-540-11319-5.
  17. Severance, Charles (1998-02-20). "Una entrevista con el Viejo del Punto Flotante" .
  18. 1 2 3 4 Goldberg, David (marzo de 1991). "Lo que todo científico informático debería saber sobre la aritmética de punto flotante" . ACM Computing Surveys . 23 (1): 5– 48. doi : 10.1145/103162.103163 . S2CID 222008826 . (Con el anexo "Diferencias entre las implementaciones de IEEE 754":,)
  19. ISO/IEC 9899:1999 - Lenguajes de programación - C . Iso.org. §F.2, nota 307."Extendido" es el formato de datos doblemente extendido de la norma IEC 60559. El término "extendido" se refiere tanto al formato común de 80 bits como al formato cuádruple de 128 bits de la norma IEC 60559.
  20. "Representación de punto flotante IEEE" . 3 de agosto de 2021.
  21. Uso de la colección de compiladores GNU, opciones i386 y x86-64 Archivado el 16/01/2015 en Wayback Machine .
  22. "long double (específico de GCC) y __float128" . StackOverflow .
  23. "Estándar de llamada a procedimiento para la arquitectura ARM de 64 bits (AArch64)" (PDF) . 22 de mayo de 2013. Archivado (PDF) del original el 31 de julio de 2013. Consultado el 22 de septiembre de 2019 .
  24. "Referencia del compilador de la cadena de herramientas del compilador ARM, versión 5.03" (PDF) . 2013. Sección 6.3 Tipos de datos básicos . Archivado (PDF) del original el 27/06/2015 . Consultado el 08/11/2019 .
  25. Kahan, William Morton (2004-11-20). "Sobre el costo de la computación de punto flotante sin aritmética extra precisa" (PDF) . Archivado (PDF) del original el 25-05-2006 . Recuperado el 19-02-2012 .
  26. "openEXR" . openEXR. Archivado del original el 8 de mayo de 2013. Recuperado el 25 de abril de 2012. Dado que la especificación de punto flotante IEEE-754 no define un formato de 16 bits, ILM creó el formato "half". Los valores half tienen 1 bit de signo, 5 bits de exponente y 10 bits de mantisa.
  27. "Introducción técnica a OpenEXR: el tipo de datos half" . openEXR . Consultado el 16 de abril de 2024 .
  28. "Análisis IEEE-754" . Consultado el 29 de agosto de 2024 .
  29. 1 2 Personal de Borland (02/07/1998) [10/03/1994]. "Conversión entre formatos binarios de Microsoft e IEEE" . Base de datos de información técnica (TI1431C.txt). Embarcadero USA / Inprise (originalmente: Borland ). ID 1400. Archivado del original el 20/02/2019 . Recuperado el 30/05/2016 . […] _fmsbintoieee(float *src4, float *dest4) […] Formato binario de MS […] orden de bytes => m3 | m2 | m1 | exponente […] m1 es el byte más significativo => sbbb|bbbb […] m3 es el byte menos significativo […] m = byte de mantisa […] s = bit de signo […] b = bit […] MBF tiene un sesgo de 128 e IEEE tiene un sesgo de 127. […] MBF coloca el punto decimal antes del bit asumido , mientras que IEEE coloca el punto decimal después del bit asumido. […] ieee_exp = msbin[3] - 2; /* en realidad, msbin[3]-1-128+127 */ […] _dmsbintoieee(double *src8, double *dest8) […] Formato binario MS […] orden de bytes => m7 | m6 | m5 | m4 | m3 | m2 | m1 | exponente […] m1 es el byte más significativo => smmm|mmmm […] m7 es el byte menos significativo […] MBF tiene un sesgo de 128 e IEEE tiene un sesgo de 1023. […] MBF coloca el punto decimal antes del bit asumido, mientras que IEEE lo coloca después del bit asumido. […] ieee_exp = msbin[7] - 128 - 1 + 1023; […]
  30. 1 2 Steil, Michael (2008-10-20). "Crea tu propia versión de Microsoft BASIC para 6502" . pagetable.com. Archivado del original el 30-05-2016 . Recuperado el 30-05-2016 .
  31. "Formato binario IEEE vs. Microsoft; Problemas de redondeo (Completo)" . Soporte técnico de Microsoft . Microsoft . 21/11/2006. ID de artículo KB35826, Q35826. Archivado del original el 28/08/2020 . Consultado el 24/02/2010 .
  32. 1 2 Kharya, Paresh (2020-05-14). "TensorFloat-32 en la GPU A100 acelera el entrenamiento de IA y HPC hasta 20 veces" . Recuperado el 2020-05-16 .
  33. "Arquitectura en profundidad de NVIDIA Hopper" . 22 de marzo de 2022.
  34. Micikevicius, Paulius; Stosic, Dusan; Burgess, Neil; Cornea, Marius; Dubey, Pradeep; Grisenthwaite, Richard; Ha, Sangwon; Heinecke, Alexander; Judd, Patrick; Kamalu, John; Mellempudi, Naveen; Oberman, Stuart; Shoeybi, Mohammad; Siu, Michael; Wu, Hao (2022-09-12). "Formatos FP8 para aprendizaje profundo". arXiv : 2209.05433 [ cs.LG ].
  35. Kahan, William Morton (11 de enero de 2006). "¿Qué tan inútiles son las evaluaciones sin sentido del redondeo en la computación de punto flotante?" (PDF) . Archivado (PDF) del original el 21 de diciembre de 2004.
  36. 1 2 Gay, David M. (1990). Conversiones binario-decimal y decimal-binario correctamente redondeadas (Informe técnico). MANUSCRITO DE ANÁLISIS NUMÉRICO 90-10, LABORATORIOS AT&T BELL. CiteSeerX 10.1.1.31.4049 . ( dtoa.c en netlab )
  37. Loitsch, Florian (2010). "Impresión rápida y precisa de números de punto flotante con enteros" (PDF) . Actas de la 31.ª Conferencia ACM SIGPLAN sobre Diseño e Implementación de Lenguajes de Programación . PLDI '10: Conferencia ACM SIGPLAN sobre Diseño e Implementación de Lenguajes de Programación. págs. 233–243 . doi : 10.1145/1806596.1806623 . ISBN  978-1-45030019-3. S2CID 910409 . Archivado (PDF) del original el 29-07-2014. 
  38. "Se agregó soporte para el algoritmo Grisu3 para double.ToString(). por mazong1123 · Solicitud de extracción n.° 14646 · dotnet/coreclr" . GitHub .
  39. Adams, Ulf (2018-12-02). "Ryū: conversión rápida de float a string" . ACM SIGPLAN Notices . 53 (4): 270– 282. doi : 10.1145/3296979.3192369 . S2CID 218472153 . 
  40. ^ Giulietti, Rafaello. "La forma Schubfach de renderizar dobles" .
  41. "abolz/Drachennest" . GitHub . 2022-11-10.
  42. "google/double-conversion" . GitHub . 21/09/2020.
  43. Lemire, Daniel (22 de marzo de 2021). "Análisis de números a un gigabyte por segundo". Software: Practice and Experience . 51 (8): 1700– 1727. arXiv : 2101.11408 . doi : 10.1002/spe.2984 . S2CID 231718830 . 
  44. Patterson, David A.; Hennessy, John L. (2014). Organización y diseño de computadoras: la interfaz hardware/software . Serie Morgan Kaufmann de arquitectura y diseño de computadoras (5.ª ed.). Waltham, Massachusetts, EE. UU.: Elsevier. pág. 793. ISBN   978-9-86605267-5.
  45. 1 2 Patente estadounidense 3037701A , Huberto M Sierra, "Medios de control aritmético de punto decimal flotante para calculadora", emitida el 5 de junio de 1962 
  46. 1 2 Kahan, William Morton (1997-10-01). "Notas de clase sobre el estado de la norma IEEE 754 para aritmética binaria de punto flotante" (PDF) . pág. 9. Archivado (PDF) del original el 22-06-2002. 
  47. "D.3.2.1" . Manuales para desarrolladores de software de las arquitecturas Intel 64 e IA-32 . Vol. 1. 
  48. Harris, Richard (octubre de 2010). "¡Vas a tener que pensar!" . Overload (99): 5–10 . ISSN 1354-3172 . Recuperado el 24 de septiembre de 2011. Mucho más preocupante es el error de cancelación, que puede producir una pérdida catastrófica de precisión. 
  49. Christopher Barker: PEP 485 -- Una función para probar la igualdad aproximada
  50. 1 2 "Sistema de defensa antimisiles Patriot: Un problema de software provocó una falla del sistema en Dharhan, Arabia Saudita" . Oficina de Contabilidad del Gobierno de EE. UU . Informe GAO IMTEC 92-26.
  51. 1 2 Skeel, Robert (julio de 1992), "Error de redondeo y el misil Patriot" (PDF) , SIAM News , 25 (4): 11 , consultado el 15 de noviembre de 2024
  52. Wilkinson, James Hardy (8 de septiembre de 2003). «Análisis de errores». En Ralston, Anthony; Reilly, Edwin D.; Hemmendinger, David (eds.). Enciclopedia de la informática . Wiley . págs. 669–674 . ISBN  978-0-470-86412-8. Consultado el 14 de mayo de 2013 .
  53. Einarsson, Bo (2005). Precisión y fiabilidad en la computación científica . Sociedad de Matemáticas Industriales y Aplicadas (SIAM). págs. 50–. ISBN  978-0-89871-815-7. Consultado el 14 de mayo de 2013 .
  54. 1 2 3 4 Higham, Nicholas John (2002). Precisión y estabilidad de los algoritmos numéricos (2.ª ed.). Sociedad de Matemáticas Industriales y Aplicadas (SIAM). págs. 27–28 , 110–123 , 493. ISBN   978-0-89871-521-7. 0-89871-355-2.
  55. Oliveira, Suely; Stewart, David E. (2006-09-07). Writing Scientific Software: A Guide to Good Style . Cambridge University Press . pp. 10–. ISBN  978-1-139-45862-7.
  56. 1 2 Kahan, William Morton (15 de julio de 2005). La aritmética de punto flotante asediada por las "decisiones empresariales" (PDF) . ARITH 17 , Simposio sobre aritmética computacional patrocinado por IEEE (Discurso principal). pp. 6, 18. Archivado (PDF) del original el 17 de marzo de 2006. Recuperado el 23 de mayo de 2013 . (Nota: Kahan estima que la incidencia de resultados excesivamente inexactos cerca de singularidades se reduce en un factor de aproximadamente 1/2000 al usar los 11 bits adicionales de precisión de la doble extensión ).
  57. Kahan, William Morton (3 de agosto de 2011). Remedios urgentemente necesarios para la imposibilidad de depurar cálculos de punto flotante de gran tamaño en ciencia e ingeniería (PDF) . Conferencia de trabajo IFIP/SIAM/NIST sobre cuantificación de la incertidumbre en la computación científica, Boulder, CO. pág. 33. Archivado (PDF) del original el 20 de junio de 2013. 
  58. 1 2 Kahan, William Morton ; Darcy, Joseph (2001) [1998-03-01]. "Cómo el punto flotante de Java perjudica a todos en todas partes" (PDF) . Archivado (PDF) del original el 16-08-2000 . Recuperado el 05-09-2003 .
  59. 1 2 3 4 Kahan, William Morton (27 de agosto de 2000). "Marketing versus Matemáticas" (PDF) . págs. 15, 35, 47. Archivado (PDF) del original el 15 de agosto de 2003. 
  60. Kahan, William Morton (12 de febrero de 1981). "¿Por qué necesitamos un estándar de aritmética de punto flotante?" (PDF) . pág. 26. Archivado (PDF) del original el 4 de diciembre de 2004. 
  61. Kahan, William Morton (4 de junio de 2001). Bindel, David (ed.). "Apuntes de clase sobre soporte de sistemas para computación científica" (PDF) . Archivado (PDF) del original el 17 de mayo de 2013.
  62. "Aritmética decimal general" . Speleotrove.com . Consultado el 25 de abril de 2012 .
  63. Christiansen, Tom; Torkington, Nathan; et al. (2006). "perlfaq4 / ¿Por qué está roto int()?" . perldoc.perl.org . Consultado el 11 de enero de 2011 . 
  64. Shewchuk, Jonathan Richard (1997). "Aritmética de punto flotante de precisión adaptativa y predicados geométricos robustos rápidos" . Geometría discreta y computacional . 18 (3): 305– 363. doi : 10.1007/PL00009321 .
  65. Kahan, William Morton ; Ivory, Melody Y. (1997-07-03). "El redondeo degrada una viga en voladizo idealizada" (PDF) . Archivado (PDF) del original el 2003-12-05.
  66. "Autovectorización en LLVM" . Documentación de LLVM 13. Admitimos operaciones de reducción de punto flotante cuando se utiliza -ffast-math .
  67. Kaylor, Andy (octubre de 2024). "Hacia matemáticas rápidas y útiles" (PDF) .
  68. "FloatingPointMath" . Wiki de GCC .
  69. "55522 – -funsafe-math-optimizations es inesperadamente dañino, especialmente con -shared" . gcc.gnu.org .
  70. "Opciones de generación de código (el compilador GNU Fortran)" . gcc.gnu.org .
  71. "Error en zheevd · Problema n.° 43 · Referencia-LAPACK/lapack" . GitHub .
  72. Becker, Heiko; Darulova, Eva; Myreen, Magnus O.; Tatlock, Zachary (2019). Icing: Soporte para optimizaciones de estilo Fast-Math en un compilador verificado . CAV 2019: Verificación asistida por computadora. Vol. 11562. pp. 155– 173. doi : 10.1007/978-3-030-25543-5_10 .  

Lecturas adicionales

  • "Estudio de formatos de punto flotante" .(Nota: Esta página ofrece un resumen muy breve de los formatos de coma flotante que se han utilizado a lo largo de los años).
  • Monniaux, David (mayo de 2008). "Los escollos de la verificación de cálculos de punto flotante" . ACM Transactions on Programming Languages ​​and Systems . 30 (3). Association for Computing Machinery (ACM) Transactions on programming languages ​​and systems (TOPLAS): 1– 41. arXiv : cs/0701192 . doi : 10.1145/1353445.1353446 . S2CID 218578808 . (Nota: Compendio de comportamientos poco intuitivos de la aritmética de punto flotante en arquitecturas populares, con implicaciones para la verificación y las pruebas de programas).
  • OpenCores . (Nota: Este sitio web contiene núcleos IP de punto flotante de código abierto para la implementación de operadores de punto flotante en dispositivos FPGA o ASIC. El proyecto double_fpu contiene el código fuente Verilog de una unidad de punto flotante de doble precisión. El proyecto fpuvhdl contiene el código fuente VHDL de una unidad de punto flotante de precisión simple).
  • Fleegal, Eric (2004). "Optimización de punto flotante de Microsoft Visual C++" . Microsoft Developer Network . Archivado del original el 6 de julio de 2017.