stringtranslate.com

Aritmética de punto flotante

Una de las primeras computadoras programables electromecánicas, la Z3 , incluía aritmética de punto flotante (réplica en exhibición en el Deutsches Museum de Munich ).

En informática , la aritmética de punto flotante ( FP ) es una aritmética que representa subconjuntos de números reales utilizando un número entero con una precisión fija, llamado significado , escalado por un exponente entero de base fija. Los números de esta forma se llaman números de punto flotante . [1] : 3  [2] : 10  Por ejemplo, 12,345 es un número de punto flotante en base diez con cinco dígitos de precisión:

Sin embargo, a diferencia de 12,345, 12,3456 no es un número de punto flotante en base diez con cinco dígitos de precisión; necesita seis dígitos de precisión; el número de punto flotante más cercano con sólo cinco dígitos es 12,346. 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 de precisión de base diez, la suma 12,345 + 1,0001 = 13,3451 podría redondearse a 13,345.

El término punto flotante se refiere al hecho de que la punta de la base del número puede "flotar" en cualquier lugar a la izquierda, a la derecha o entre los dígitos significativos del número. Esta posición está indicada por el exponente, por lo que el punto flotante puede considerarse una forma de notación científica .

Se puede utilizar un sistema de punto flotante para representar, con un número fijo de dígitos, números de órdenes de magnitud muy diferentes , como el número de metros entre galaxias o entre protones en un átomo . Por esta razón, la aritmética de punto flotante se utiliza a menudo para permitir números reales muy pequeños y muy grandes que requieren tiempos de procesamiento rápidos. El resultado de este rango dinámico es que 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 valores representables.
Versión aumentada arriba que muestra ambos signos de valores representables

A lo largo de los años, se han utilizado en las computadoras una variedad de representaciones de punto flotante. En 1985, se estableció el estándar IEEE 754 para 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, comúnmente medida 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.

Una unidad de punto flotante (FPU, coloquialmente un coprocesador matemático ) es una parte de un sistema informático especialmente diseñado para realizar operaciones con números de punto flotante.

Descripción general

Números de punto flotante

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

Existen varios mecanismos mediante los cuales cadenas de dígitos pueden representar números. En notación matemática estándar, la cadena de dígitos puede tener cualquier longitud y la ubicación del punto de la base se indica colocando un carácter de "punto" explícito (punto o coma) allí. Si no se especifica el punto de base, entonces la cadena representa implícitamente un número entero y el punto de base no declarado estaría en el extremo derecho de la cadena, junto al dígito menos significativo. En los sistemas de punto fijo , se especifica una posición en la cadena para el punto de base. Por lo tanto, un esquema de punto fijo podría utilizar una cadena de 8 dígitos decimales con el punto decimal en el medio, donde "00012345" representaría 0001,2345.

En notación científica , el número dado se escala en una potencia de 10 , de modo que se encuentre dentro de un rango específico, generalmente entre 1 y 10, y el punto de la base aparece 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 coma flotante consta de:

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

Usando base 10 (la conocida notación decimal ) como ejemplo, el número152,853.5047 , que tiene diez dígitos decimales de precisión, se representa como el significado1.528.535.047 junto con 5 como exponente. Para determinar el valor real, se coloca un punto decimal después del primer dígito del significado y el resultado se multiplica por 10.5 para dar1.528535047 × 10 5 , 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:

donde s es el significado (ignorando cualquier punto decimal implícito), p es la precisión (el número de dígitos en el significado), 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 coma flotante, siendo la base dos ( binaria ) la más común, seguida de la base diez ( coma flotante decimal ) y otras variedades menos comunes, como la base dieciséis ( coma flotante hexadecimal). [4] [5] [nb 3] ), base ocho (coma flotante octal [1] [5] [6] [4] [nb 4] ), base cuatro (coma flotante cuaternaria [7] [5] [nb 5] ), base tres ( coma flotante ternaria equilibrada [1] ) e incluso base 256 [5] [nb 6] y base65.536 . [8] [nota 7]

Un número de coma flotante es un número racional , porque se puede representar como un número entero dividido por otro; Por ejemplo1,45 × 10 3 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 se puede representar exactamente mediante binario (0,010101...) o decimal (0,333...), pero en base 3 , es trivial (0,1 o 1×3 −1 ). Las ocasiones en las que se producen expansiones infinitas dependen de la base y sus factores primos .

La forma en que se almacenan el significado (incluido su signo) y el exponente en una computadora 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 binaria de punto flotante de precisión simple (32 bits), por lo que el significado es una cadena de 24 bits . Por ejemplo, los primeros 33 bits del número π son:

En esta expansión binaria, indiquemos las posiciones desde 0 (bit más a la izquierda o bit más significativo) hasta 32 (bit más a la derecha). El significado de 24 bits se detendrá en la posición 23, que se muestra como el bit subrayado.0 arriba. La siguiente broca, en la posición 24, se llama broca redonda o broca de redondeo . Se utiliza para redondear la aproximación de 33 bits al número de 24 bits más cercano (existen reglas específicas para los valores intermedios , lo cual no es el caso aquí). Esta parte, que es1 en este ejemplo, se suma al número entero formado por los 24 bits más a la izquierda, lo que produce:

Cuando esto se almacena en la memoria usando la codificación IEEE 754, se convierte en el significado s . Se supone que el significado tiene un punto binario a la derecha del bit más a la izquierda. Entonces, la representación binaria de π se calcula de izquierda a derecha de la siguiente manera:

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

Se puede exigir que el dígito más significativo del significado 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 llama normalización . Para formatos binarios (que utilizan sólo los dígitos0 y1 ), este dígito distinto de cero es necesariamente1 . Por tanto, no es necesario representarlo en memoria, permitiendo que el formato tenga un bit más de precisión. Esta regla se denomina de diversas formas convención de bits inicial , convención de bits implícita , convención de bits ocultos , [1] o convención de bits asumida .

Alternativas a los números de punto flotante

La representación en coma flotante es, con diferencia, la forma más común de representar en ordenadores una aproximación a números reales. Sin embargo, existen alternativas:

Historia

Leonardo Torres Quevedo , en 1914 publicó un análisis de coma flotante basado en el motor analítico

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 como n x 10 y ofreció tres reglas mediante las cuales se podría implementar una manipulación consistente de números de punto flotante por parte de las máquinas. Para Torres, " n siempre será el mismo número de dígitos (p.ej. seis), el primer dígito de n será del orden de décimas, el segundo de centésimas, etc, y se escribirá cada cantidad en la forma: n ; m ". El formato que propuso muestra la necesidad de un significado de tamaño fijo como se usa actualmente para los datos de punto flotante, fijando la ubicación del punto decimal en el significado para que cada representación sea única, y cómo formatear dichos números especificando una sintaxis. para ser utilizado que podía ser ingresado 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 binaria programable ; [13] utiliza una representación numérica binaria de punto flotante de 24 bits con un exponente con signo de 7 bits, un significado de 17 bits (incluido un bit implícito) y un bit de signo. [14] El Z3 , más confiable , basado en relés , terminado en 1941, tiene representaciones de infinitos positivos y negativos; en particular, implementa operaciones definidas con infinito, como , y se detiene en operaciones no definidas, como .

Zuse también propuso, pero no completó, una aritmética de punto flotante cuidadosamente redondeada que incluye representaciones NaN, anticipando las características del estándar IEEE en cuatro décadas. [15] Por el contrario, von Neumann desaconsejó los números de punto flotante para la máquina IAS de 1951 , argumentando que es preferible la aritmética de punto fijo. [15]

La primera computadora comercial con hardware de punto flotante fue la computadora Z4 de Zuse , diseñada en 1942-1945. En 1946, los Laboratorios Bell introdujeron el Modelo V , que implementaba números decimales de punto flotante . [dieciséis]

El Pilot ACE tiene aritmética binaria de punto flotante y entró en funcionamiento en 1950 en el Laboratorio Nacional de Física del Reino Unido . Posteriormente, treinta y tres se vendieron comercialmente como English Electric DEUCE . En realidad, la aritmética se implementa en software, pero con 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 más rápida que la de muchos ordenadores de la competencia.

En 1954 siguió el IBM 704 producido en masa ; introdujo el uso de un exponente sesgado . Durante muchas décadas después de eso, el hardware de punto flotante fue típicamente una característica opcional, y se decía que las computadoras que lo tenían eran "computadoras científicas" o tenían capacidad de " computación científica " (SC) (ver también Extensiones para Computación Científica (XSC). )). No fue hasta el lanzamiento del Intel i486 en 1989 que las computadoras personales de uso general tuvieron capacidad de punto flotante en el hardware como característica estándar.

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

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

Inicialmente, las computadoras usaban muchas representaciones diferentes para los números de punto 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 nivel superior; Estos estándares de punto flotante de los fabricantes diferían en el tamaño de las palabras, las representaciones, el comportamiento de redondeo y la precisión general de las operaciones. La compatibilidad de punto flotante entre múltiples sistemas informáticos necesitaba desesperadamente una 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 había vuelto común. Este estándar se basó en gran medida en una propuesta de Intel, que estaba diseñando el coprocesador numérico i8087 ; Motorola, que estaba diseñando el 68000 casi al mismo tiempo, también hizo aportaciones importantes.

En 1989, el matemático e informático William Kahan fue honrado con el Premio Turing por ser el arquitecto principal detrás de esta propuesta; Fue ayudado por su alumno Jerome Coonen y un profesor visitante, Harold Stone . [17]

Entre las innovaciones x86 se encuentran estas:

Rango de números de punto flotante

Un número de coma flotante se compone de dos componentes de coma fija , 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 de punto flotante depende linealmente del rango significativo y exponencialmente del rango del componente exponencial, lo que otorga un rango notablemente más amplio al número.

En un sistema informático típico, un número binario de punto flotante 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 números de punto flotante normales positivos en este formato es de 2 −1022  ≈ 2 × 10 −308 a aproximadamente 2 1024  ≈ 2 × 10 308 .

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

es .

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

Nivel de desbordamiento = UFL = ,

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

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

Nivel de desbordamiento = OFL = ,

que tiene B − 1 como valor para cada dígito del significado 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: punto flotante en las computadoras modernas

El IEEE estandarizó la representación informática de números binarios de punto flotante en IEEE 754 (también conocido como IEC 60559) en 1985. Este primer estándar lo siguen casi todas las máquinas modernas. Fue revisado en 2008 . Los mainframes IBM admiten el formato de punto flotante hexadecimal propio de IBM y el punto flotante decimal IEEE 754-2008 , además del formato binario IEEE 754. La serie Cray T90 tenía una versión IEEE, pero el SV1 todavía usa el formato de punto flotante Cray. [ cita necesaria ]

La norma prevé muchos formatos estrechamente relacionados, que se diferencian sólo en unos pocos 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: [ cita necesaria ]

Aumentar la precisión de la representación de punto flotante generalmente reduce la cantidad de error de redondeo acumulado causado por los cálculos intermedios. [24] Otros formatos IEEE incluyen:

Cualquier número entero con valor absoluto menor que 2 24 se puede representar exactamente en el formato de precisión simple, y cualquier número entero con valor absoluto menor que 2 53 se puede representar exactamente en el formato de doble precisión. Además, se puede representar una amplia gama de potencias de 2 veces dicho número. Estas propiedades a veces se utilizan para datos puramente enteros, para obtener enteros de 53 bits en plataformas que tienen flotantes 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, tal como la define el estándar IEEE, es un poco diferente de la comparación habitual de números enteros. El cero negativo y el positivo se comparan iguales, y cada NaN se compara de manera desigual con cada valor, incluido él mismo. Todos los números finitos de coma flotante son estrictamente menores que +∞ y estrictamente mayores que −∞ , y están ordenados de la misma manera que sus valores (en el conjunto de los números reales).

Representación interna

Los números de coma flotante generalmente se empaquetan en un dato de computadora como el bit de signo, el campo de exponente y el significado o mantisa, de izquierda a derecha. Para los formatos binarios IEEE 754 (básico y extendido) que tienen 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 al que se le agrega un "sesgo" fijo. Los valores de todos los ceros en este campo están reservados para los ceros y los números subnormales ; Los valores de todos los unos están reservados para los infinitos y los NaN. El rango de exponentes para números normales es [−126, 127] para precisión simple, [−1022, 1023] para doble o [−16382, 16383] para cuádruple. Los números normales excluyen valores subnormales, ceros, infinitos y NaN.

En los formatos de intercambio binario IEEE, el primer bit de un significado normalizado no se almacena realmente en el dato de la computadora. Se llama bit "oculto" o "implícito". Debido a esto, el formato de precisión simple en realidad tiene un significado de 24 bits de precisión, el formato de doble precisión tiene 53 y el cuádruple tiene 113.

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

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

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

y el diseño de 64 bits ("doble") es similar.

Otros formatos de punto flotante notables

Además de los formatos estándar IEEE 754 ampliamente utilizados , se utilizan, o se han utilizado, otros formatos de punto flotante en determinadas áreas específicas de dominio.

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 terminal en la base relevante (por ejemplo, una expansión decimal terminal en base 10 o una expansión binaria terminal en base 2). Se deben aproximar los números irracionales, como π o √2, o los números racionales no terminantes. 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 se puede representar exactamente si solo hay ocho dígitos decimales de precisión disponibles (se redondearía a uno de los dos valores representables, 12345678 × 10 1 o 12345679 × 10 1 ), lo mismo se aplica a no -dígitos terminales (. 5 se redondeará a .55555555 o .55555556).

Cuando un número se representa en algún formato (como una cadena de caracteres) que no es una representación nativa de punto flotante admitida en una implementación informática, será necesaria una conversión antes de poder utilizarlo en esa implementación. Si el número se puede representar exactamente en formato de punto flotante, entonces la conversión es exacta. Si no hay una representación exacta, entonces la conversión requiere elegir qué número de punto flotante usar para representar el valor original. La representación elegida tendrá un valor diferente al original, y el valor así ajustado se denomina valor redondeado .

Que un número racional tenga o no un desarrollo terminal depende de la base. Por ejemplo, en base 10 el número 1/2 tiene una expansión terminal (0,5) mientras que el número 1/3 no (0,333...). En base 2, solo terminan los racionales con denominadores que son potencias de 2 (como 1/2 o 3/16). Cualquier racional con un denominador que tenga un factor primo distinto de 2 tendrá una expansión binaria infinita. Esto significa que es posible que sea necesario aproximar los números que parecen cortos y exactos cuando se escriben en formato decimal cuando se convierten a punto flotante binario. Por ejemplo, el número decimal 0,1 no se puede representar en coma flotante binaria de precisión finita; la representación binaria exacta tendría una secuencia "1100" que continuaría sin fin:

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

donde, como antes, s es el significado 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 redondeando a una precisión de 24 bits.

En coma flotante binaria 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 valor real 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 la máquina épsilon .

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

Modos de redondeo

El redondeo se utiliza cuando el resultado exacto de una operación de punto flotante (o una conversión al formato de punto flotante) necesitaría más dígitos de los que hay en el significado. IEEE 754 requiere un redondeo correcto : es decir, el resultado redondeado es como si se usara aritmética infinitamente precisa para calcular el valor y luego se redondeara (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 a pares , a veces llamado redondeo bancario) se usa más comúnmente. Este método redondea el resultado ideal (infinitamente preciso) 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 el significado termine en dígito par. El estándar IEEE 754 requiere que se aplique el mismo redondeo a todas las operaciones algebraicas fundamentales, incluidas la raíz cuadrada y las conversiones, cuando hay un resultado numérico (que no sea NaN). Significa que los resultados de las operaciones IEEE 754 están completamente determinados en todos los bits del resultado, excepto en la representación de NaN. (Las funciones de "biblioteca", como el coseno y el registro, no son obligatorias).

También se encuentran disponibles opciones de redondeo alternativas. IEEE 754 especifica los siguientes modos de redondeo:

Los modos alternativos son útiles cuando se debe limitar la cantidad de error que se introduce. Las aplicaciones que requieren un error acotado son el 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, entonces es probable que sea numéricamente inestable y esté afectada por un error de redondeo. [33]

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

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

Muchos tiempos de ejecución de lenguajes modernos utilizan Grisu3 con un respaldo Dragon4. [40]

Conversión de decimal a binario

El problema de analizar una cadena decimal en una representación binaria de FP es complejo, y no apareció un analizador preciso hasta el trabajo de Clinger de 1990 (implementado en dtoa.c). [34] También se ha avanzado en la dirección de un análisis más rápido. [41]

Operaciones de punto flotante

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

Adición y sustracción

Un método sencillo para sumar números de punto flotante es representarlos primero con el mismo exponente. En el siguiente ejemplo, el segundo número se desplaza tres dígitos hacia la derecha y luego 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)+ mi=2; s=1,017654 (101,7654)
 e=5; s=1,234567+e=5; s=0,001017654 (después del cambio)-------------------- e=5; s=1,235584654 (suma verdadera: 123558,4654)

Este es el verdadero resultado, 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 más bajos del segundo operando (654) prácticamente se pierden. Este es un error de redondeo . En casos extremos, la suma de dos números distintos de cero puede ser igual a uno de ellos:

 e=5; s=1,234567+ mi=−3; s=9,876543
 e=5; s=1,234567+e=5; s=0.00000009876543 (después del cambio)---------------------- e=5; s=1.23456709876543 (suma verdadera) e=5; s=1,234567 (después de redondear y normalizar)

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

Otro problema de pérdida de significancia 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 racionales 123457,1467 y 123456,659.

 e=5; s=1,234571− e=5; s=1,234567---------------- e=5; s=0,000004 mi=-1; s=4.000000 (después de redondear y normalizar)

La diferencia de punto flotante se calcula exactamente porque los números son cercanos; el lema de Sterbenz garantiza esto, incluso en caso de desbordamiento cuando se admite un desbordamiento 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. [42] [44] Esta cancelación ilustra el peligro de asumir que todos los dígitos de un resultado calculado son significativos. Tratar las consecuencias de estos errores es un tema del análisis numérico ; consulte también Problemas de precisión.

Multiplicación y división

Para multiplicar, se multiplican los significados 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 real) e=8; s=25,64854 (después de redondear) e=9; s=2,564854 (después de la normalización)

De manera similar, la división se logra restando el exponente del divisor del exponente del dividendo y dividiendo el significado del dividendo por el significado del divisor.

No hay problemas de cancelación o absorción con la multiplicación o división, aunque se pueden acumular pequeños errores a medida que se realizan operaciones sucesivas. [42] En la práctica, la forma en que se llevan a cabo estas operaciones en lógica digital puede ser bastante compleja (ver Algoritmo de multiplicación de Booth y Algoritmo de división ). [nb 9] Para conocer un método rápido y sencillo, consulte el método Horner .

Sintaxis literal

Los literales de los números de coma flotante dependen de los idiomas. Normalmente utilizan eo Epara denotar 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 números 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:

Cómo afrontar casos excepcionales

El cálculo de punto flotante en una computadora puede generar tres tipos de problemas:

Antes del estándar IEEE, tales condiciones generalmente provocaban que el programa terminara o desencadenaban algún tipo de trampa que el programador podía detectar. El funcionamiento de esto dependía del sistema, lo que significaba que los programas de punto flotante no eran portátiles . (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 es necesariamente un error, y es un uso diferente al que se define típicamente en lenguajes de programación como C++ o Java, en el que un " excepción " es un flujo de control alternativo, más cercano a lo que se denomina "trampa" en la terminología IEEE 754).

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

Sin embargo, el estándar IEEE 754 original no recomendaba operaciones para manejar tales conjuntos de bits de indicadores de excepción aritmética. Entonces, si bien 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 bits de indicador de estado. La versión 2008 del estándar IEEE 754 ahora especifica algunas operaciones para acceder y manejar los bits de bandera aritmética. El modelo de programación se basa en un único subproceso de ejecución y su uso por parte de múltiples subprocesos debe manejarse por un medio fuera del estándar (por ejemplo, C11 especifica que las banderas tienen almacenamiento local de subprocesos ).

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

Fig. 1: resistencias en paralelo, con resistencia total

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 puedan ignorar en la mayoría de los códigos. inexact devuelve un resultado correctamente redondeado 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. [45] dividir por cero devuelve infinito exactamente, lo que normalmente dividirá un número finito y, por lo tanto, dará cero, o dará una excepción no válida posteriormente si no, y por lo tanto, normalmente también se puede ignorar. Por ejemplo, la resistencia efectiva de n resistencias en paralelo (ver figura 1) viene dada por . Si se desarrolla un cortocircuito con el valor 0, devolverá +infinito, lo que dará un resultado final de 0, como se esperaba [46] (consulte el ejemplo de fracción continua de la justificación del diseño IEEE 754 para ver otro ejemplo).

Por lo general, las excepciones de desbordamiento y no válidas 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 en valores fuera de su dominio, devolviendo NaN y un indicador de excepción no válido que se ignorará hasta encontrar un punto de inicio útil. [45]

Problemas de precisión

El hecho de que los números de punto flotante no puedan representar con precisión todos los números reales y que las operaciones de punto flotante no puedan representar con precisión las operaciones aritméticas verdaderas conduce a muchas situaciones sorprendentes. Esto está relacionado con la precisión finita con la que las computadoras generalmente representan 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 binario32 IEEE 754 con su significado 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.

Al elevar al cuadrado este número se obtiene

0.010000000298023226097399174250313080847263336181640625 exactamente.

Cuadrándolo con redondeo a la precisión de 24 bits se obtiene

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) significa que un intento de cálculo de tan(π/2) no producirá un resultado infinito, ni siquiera se desbordará en los formatos habituales de punto flotante (asumiendo una precisión). implementación del bronceado). Simplemente no es posible que el hardware de punto flotante estándar intente calcular tan(π/2), porque π/2 no se puede representar exactamente. Este cálculo en C:

/* Suficientes dígitos para asegurarnos de obtener la aproximación correcta. */ doble pi = 3,1415926535897932384626433832795 ; doble 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 sen(π) no arrojará cero. El resultado será (aproximadamente) 0,1225 × 10 −15 en precisión doble, o −0,8742 × 10 −7 en precisión simple. [nota 10]

Si bien la suma y la multiplicación en 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 significativa 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 números como π y 0,1 con exactitud y otras ligeras imprecisiones, pueden ocurrir los siguientes fenómenos:

Incidentes

Precisión de la máquina y análisis de errores hacia atrás.

La precisión de la máquina es una cantidad que caracteriza la precisión de un sistema de punto flotante y se utiliza en el análisis de errores hacia atrás de algoritmos de punto flotante. También se le conoce como redondeo unitario o épsilon de máquina . Generalmente denominado Ε mach , su valor depende del redondeo particular que se utilice.

Con redondeo a cero,

BPB

Esto es importante ya que limita el error relativo al representar cualquier número real x distinto de cero dentro del rango normalizado de un sistema de punto flotante:

El análisis de errores hacia atrás, cuya teoría fue desarrollada y popularizada por James H. Wilkinson , se puede utilizar para establecer que un algoritmo que implementa una función numérica es numéricamente estable. [50] El enfoque básico es mostrar que aunque 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 "merece". El algoritmo se define entonces como retroestable . La estabilidad es una medida de la sensibilidad a los errores de redondeo de un procedimiento numérico determinado; por el contrario, el número de condición de una función para un problema determinado 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. [51]

Como ejemplo trivial, considere una expresión simple que proporcione el producto interno de vectores (de longitud dos) y , entonces

dónde

dónde

por definición, que es la suma de dos datos de entrada ligeramente perturbados (del orden de Ε mach ) y, por lo tanto, es estable hacia atrás. Para ejemplos más realistas en álgebra lineal numérica , consulte Higham 2002 [52] y otras referencias a continuación.

Minimizar el efecto de los problemas de precisión.

Aunque se garantiza que las operaciones aritméticas individuales de IEEE 754 tienen una precisión de medio ULP , las fórmulas más complicadas 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 que están 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 tal 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 (cero) en un algoritmo con una precisión mayor que la que requiere el resultado final, [ 53] que puede eliminar o reducir en órdenes de magnitud, [54] tal 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. [55] [nota 11]

Por ejemplo, el siguiente algoritmo es una implementación directa para calcular la función A ( x ) = ( x −1) / (exp( x −1) − 1) que está bien condicionada en 1.0, [nb 12] sin embargo puede Se 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. [56]

doble A ( doble X )  { doble Y , Z ; // [1]    Y = X - 1,0 ;     Z = exp ( Y );   si ( Z != 1.0 )    Z = Y / ( Z - 1,0 ); // [2]        devolver Z ; }

Sin embargo, si todos los cálculos intermedios se realizan con precisión extendida (por ejemplo, configurando la línea [1] en C99 long double ), entonces se puede mantener hasta la precisión total en el resultado doble final. [nb 13] Alternativamente, un análisis numérico del algoritmo revela que si se realiza el siguiente cambio no obvio en la línea [2]:

Z = iniciar sesión ( Z ) / ( Z - 1,0 );      

entonces el algoritmo se vuelve numéricamente estable y puede calcular con doble precisión total.

Para mantener las propiedades de programas numéricamente estables tan cuidadosamente construidos, se requiere un manejo cuidadoso por parte del compilador . Ciertas "optimizaciones" que los compiladores podrían realizar (por ejemplo, reordenar operaciones) pueden ir en contra de los objetivos de un software de buen comportamiento. Existe cierta controversia sobre las fallas de los compiladores y los diseños de lenguajes en esta área: 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á más allá del alcance de este artículo, y se remite al lector a [52] [57] 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 [57] el riesgo de anomalías numéricas, además de, o en lugar de, un análisis numérico más cuidadoso. Estos incluyen: como se señaló anteriormente, calcular todas las expresiones y resultados intermedios con la mayor precisión admitida por el hardware (una regla general es llevar el doble de precisión del resultado deseado, es decir, calcular con doble precisión para obtener un resultado final de precisión simple, o en precisión doble extendida o cuádruple para resultados de hasta doble precisión [58] ); y redondear los datos de entrada y los resultados solo a la precisión requerida y respaldada por los datos de entrada (llevar un exceso de precisión en el resultado final más allá de lo requerido y respaldado por los datos de entrada puede ser engañoso, aumenta el costo de almacenamiento y disminuye la velocidad, y el exceso de bits puede afectan la convergencia de procedimientos numéricos: [59] en particular, la primera forma del ejemplo iterativo que se proporciona 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 pueden representarse exactamente en coma flotante binaria, dicha aritmética funciona mejor cuando simplemente se utiliza 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 en el peor de los casos, cuando se espera modelar las interacciones de cantidades expresadas como cadenas decimales que se espera que sean exactas. [54] [57] Un ejemplo del último caso son los cálculos financieros. Por esta razón, el software financiero tiende a no utilizar una representación numérica binaria de punto flotante. [60] 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 binarias de punto flotante cuando se aplican a valores decimales exactos ingresados ​​por humanos. y hacer que la aritmética siempre se comporte como se espera cuando los números se imprimen en decimal.

Es posible que las expectativas de las matemáticas no se cumplan en el campo de la computación de punto flotante. Por ejemplo, se sabe que , y que , sin embargo, no se puede confiar en estos hechos cuando las cantidades involucradas son el resultado de un cálculo 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==0will, en la mayoría de las computadoras, no son verdaderas [61] (en IEEE 754, la doble precisión, por ejemplo, 0.6/0.2 - 3es aproximadamente igual a -4.44089209850063e-16). En consecuencia, estas pruebas a veces se reemplazan con comparaciones "difusas" ( if (abs(x-y) < epsilon) ..., donde épsilon es suficientemente pequeño y está adaptado a la aplicación, como 1.0E-13). La sabiduría de hacer esto varía mucho y puede requerir un análisis numérico para limitar el épsilon. [52] Los valores derivados de la representación de datos primarios y sus comparaciones deben realizarse con una precisión más amplia y extendida para minimizar el riesgo de tales inconsistencias debido a errores de redondeo. [57] A menudo es mejor organizar el código de tal manera que tales pruebas sean innecesarias. Por ejemplo, en geometría computacional , se pueden realizar pruebas exactas de si un punto se encuentra fuera o sobre una línea o plano definido por otros puntos utilizando precisión adaptativa o métodos aritméticos exactos. [62]

Los pequeños errores en la aritmética de punto flotante pueden aumentar cuando los algoritmos matemáticos realizan operaciones una enorme cantidad 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 mucho cuidado, utilizando enfoques numéricos como el refinamiento iterativo , para que funcionen bien. [63]

La suma de un vector de valores de punto flotante es un algoritmo básico en la informática científica , por lo que es esencial saber cuándo puede ocurrir una pérdida de significancia. Por ejemplo, si uno está sumando una gran cantidad de números, los sumandos individuales son muy pequeños en comparación con la suma. Esto puede llevar a una pérdida de importancia. Una adición típica sería entonces algo como

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

Los 3 dígitos inferiores de los sumandos se pierden efectivamente. Supongamos, por ejemplo, que es necesario sumar muchos números, todos aproximadamente iguales a 3. Después de sumar 1.000 de ellos, la suma acumulada es aproximadamente 3.000; los dígitos perdidos no se recuperan. Se puede utilizar el algoritmo de suma de Kahan para reducir los errores. [52]

El error de redondeo puede afectar la convergencia y precisión de los procedimientos numéricos iterativos. Por ejemplo, Arquímedes aproximó π calculando los perímetros de los polígonos que inscribían y circunscribían un círculo, comenzando con los hexágonos y duplicando sucesivamente el número de lados. Como se señaló anteriormente, los cálculos se pueden reorganizar de una manera que sea 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: [ cita necesaria ]

Aquí hay un cálculo utilizando la aritmética "doble" IEEE (un significado 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 3748771353666810 3.141592 9278733740748 3.141592 927385097988511 3.141592 7256228504127 3.141592 722038614837712 3.1415926 717412858693 3.1415926 70701999212513 3.1415926 189011456060 3.14159265 7867845472814 3.1415926 717412858693 3.14159265 4659307370915 3.14159 19358822321783 3.141592653 857173011916 3.1415926 717412858693 3.141592653 656639422217 3.1415 810075796233302 3.141592653 606506191318 3.1415926 717412858693 3.1415926535 93972883619 3.141 4061547378810956 3.1415926535 90839390120 3,14 05434924008406305 3,1415926535 90056016821 3.14 00068646912273617 3.141592653589 860839622 3.1 349453756585929919 3.141592653589 812211823 3.14 00068646912273617 3.14159265358979 9555224 3 .2245152435345525443 3.14159265358979 6890725 3.14159265358979 6224626 3.14159265358979 6224627 3.14159265358979 6224628 3.14159265358979 62246 El valor verdadero es 3.14159265358979323846264338327...

Si bien las dos formas de la fórmula de recurrencia son claramente equivalentes matemáticamente, [nb 14] la primera resta 1 a un número extremadamente cercano a 1, lo que lleva a 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 al principio, pero luego se deteriora. Nunca supera los 8 dígitos, aunque la aritmética de 53 bits debería tener una precisión de unos 16 dígitos. Cuando se utiliza la segunda forma de 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 tanta eficacia como lo harían con la aritmética de números enteros y de punto fijo, lo que presenta un obstáculo en optimizaciones como la eliminación de subexpresiones comunes y la autovectorización . [64] La opción "matemática rápida" en muchos compiladores (ICC, GCC, Clang, MSVC...) activa la reasociación junto con suposiciones inseguras como la falta de NaN y números infinitos en IEEE 754. Algunos compiladores también ofrecen información más granular opciones para activar solo la reasociación. En cualquier caso, el programador está expuesto a muchos de los problemas de precisión mencionados anteriormente en la parte del programa que utiliza matemáticas "rápidas". [sesenta y cinco]

En algunos compiladores (GCC y Clang), activar las matemáticas "rápidas" puede hacer que el programa desactive los flotadores anormales al inicio, lo que afecta el comportamiento del punto flotante no solo del código generado, sino también de cualquier programa que utilice dicho código como biblioteca . [66]

En la mayoría de los compiladores de Fortran , según lo permite el estándar Fortran ISO/IEC 1539-1:2004, la reasociación es la opción predeterminada, y la rotura se evita en gran medida mediante la configuración "proteger pares" (también activada de forma predeterminada). Esta configuración evita que el compilador se reasocia más allá de los límites de los paréntesis. [67] Intel Fortran Compiler es un caso atípico notable. [68]

Un problema común en las matemáticas "rápidas" es que es posible que las subexpresiones no se optimicen de manera idéntica de un lugar a otro, 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 optimizaciones matemáticas "rápidas" se ve en Icing , un compilador verificado. [69]

Ver también

Notas

  1. ^ Algunos autores también llaman mantisa al significado de un número de punto flotante ; no debe confundirse con la mantisa de un logaritmo . Algunos también utilizan términos algo vagos como coeficiente o argumento . El uso del término fracción por parte de algunos autores también es potencialmente engañoso. El término característica (como lo usa, por ejemplo, CDC ) es ambiguo, ya que históricamente también se usó para especificar alguna forma de exponente de números de punto flotante.
  2. ^ El exponente de un número de coma flotante a veces también se denomina escala . El término característica (para exponente sesgado , sesgo de exponente o representación excesiva de n ) es ambiguo, ya que históricamente también se usó para especificar el significado de los números de punto flotante.
  3. ^ La aritmética de punto flotante hexadecimal (base-16) se utiliza en IBM System 360 (1964) y 370 (1970), así como en varias máquinas IBM más nuevas, en RCA Spectra 70 (1964), Siemens 4004 (1965), Mainframes de las series 7.700 (1974), 7.800, 7.500 (1977) y sus sucesores, los mainframes de la serie Unidata 7.000, las computadoras Manchester MU5 (1972), HEP (1982) y en familias de mainframes compatibles con 360/370 fabricadas por Fujitsu, Amdahl. y Hitachi. También se utiliza en 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), SEL Systems 85 y 86, así como en SDS Sigma 5 (1967), 7 (1966) y Xerox Sigma 9 (1970).
  4. ^ La aritmética de coma flotante octal (base-8) se utiliza en las computadoras Ferranti Atlas (1962), Burroughs B5500 (1964), Burroughs B5700 (1971), Burroughs B6700 (1971) y Burroughs B7700 (1972).
  5. ^ La aritmética de punto flotante cuaternario (base 4) se utiliza en la computadora Illinois ILLIAC II (1962). También se utiliza en los sistemas de estudio de sitios de alta resolución Digital Field System DFS IV y V.
  6. ^ La aritmética de punto flotante base-256 se utiliza en la computadora R1 del Rice Institute (desde 1958).
  7. ^ La aritmética de punto flotante base-65536 se utiliza en la computadora MANIAC II (1956).
  8. ^ El hardware de la computadora no calcula necesariamente 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 condujo una vez a un error famoso. Una versión anterior del chip Intel Pentium se envió con una instrucción de división que, en raras ocasiones, daba resultados ligeramente incorrectos. Se habían enviado muchas computadoras antes de que se descubriera el error. Hasta que se reemplazaron las computadoras defectuosas, se desarrollaron versiones parcheadas de compiladores que podrían evitar los casos de falla. Consulte Error de Pentium FDIV .
  10. ^ Pero un intento de calcular cos(π) produce -1 exactamente. Dado que la derivada es casi cero cerca de π, el efecto de la inexactitud en el argumento es mucho menor que el espaciado de los números de punto flotante alrededor de −1, y el resultado redondeado es exacto.
  11. ^ William Kahan señala: "Excepto en situaciones extremadamente poco comunes, la aritmética extraprecisa generalmente atenúa los riesgos debidos al redondeo a un costo mucho menor que el precio de un analista de errores competente".
  12. ^ La expansión de Taylor de esta función demuestra que está bien condicionada cerca de 1: A(x) = 1 − (x−1)/2 + (x−1)^2/12 − (x−1)^4/ 720 + (x−1)^6/30240 − (x−1)^8/1209600 + ... para |x−1| <π.
  13. ^ Si long double es de precisión cuádruple IEEE , entonces se conserva la precisión doble completa; si long double es precisión doble extendida IEEE , entonces se retiene la precisión adicional, pero no completa.
  14. ^ La equivalencia de las dos formas se puede verificar algebraicamente observando que el denominador de la fracción en la segunda forma es el conjugado del numerador de la primera. Multiplicando la parte superior e inferior de la primera expresión por este conjugado, se obtiene la segunda expresión.

Referencias

  1. ^ abcdef 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. ^ ab Sterbenz, Pat H. (1974). Computación de punto flotante. Englewood Cliffs, Nueva Jersey, Estados Unidos: Prentice-Hall. ISBN 0-13-322495-3.
  3. ^ Smith, Steven W. (1997). "Capítulo 28, Punto fijo versus punto flotante". La guía para científicos e ingenieros sobre el procesamiento de señales digitales . Pub técnico de California. pag. 514.ISBN _ 978-0-9660176-3-2. Consultado el 31 de diciembre de 2012 .
  4. ^ ab 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 .[1] (NB. Esta referencia indica incorrectamente que la base de coma flotante del MANIAC II es 256, cuando en realidad es 65536).
  5. ^ abcd Beebe, Nelson HF (22 de agosto de 2017). "Capítulo H. Arquitecturas históricas de punto flotante". Manual de computación de funciones matemáticas: programación utilizando la biblioteca de software portátil MathCW (1ª ed.). Salt Lake City, UT, EE.UU.: Springer International Publishing AG . pag. 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 coma flotante decimal", quadibloc , archivado desde el original el 3 de julio de 2018 , consultado el 16 de julio de 2018
  7. ^ Parkinson, Roger (7 de diciembre de 2000). "Capítulo 2 - Sistemas digitales de levantamiento de sitios de alta resolución - Capítulo 2.1 - Sistemas digitales de registro de campo". Estudios de sitio de alta resolución (1ª ed.). Prensa CRC . pag. 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 cuaternario y utilizaban pasos de ganancia de 12 dB. […](256 páginas)
  8. ^ Lázaro, Roger B. (30 de enero de 1957) [1 de octubre de 1956]. "MANÍACO II" (PDF) . Los Alamos, NM, EE.UU.: Laboratorio Científico de Los Alamos de la Universidad de California. pag. 14. LA-2083. Archivado (PDF) desde el original el 7 de agosto de 2018 . Consultado el 7 de agosto de 2018 . […] la base flotante del Maniac, que es 2 16 = 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 a la izquierda, el gran tamaño de palabra de 48 bits garantiza una significación 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 los orígenes, (pdf), p. 545, Computadoras digitales: orígenes, Enciclopedia de Ciencias de la Computación, enero de 2003.
  13. ^ Rojas, Raúl (abril-junio de 1997). "El legado de Konrad Zuse: la arquitectura del Z1 y Z3" (PDF) . Anales IEEE de la historia de la informática . 19 (2): 5–16. doi : 10.1109/85.586067. Archivado (PDF) desde el original el 3 de julio de 2022 . Consultado el 3 de julio de 2022 .(12 páginas)
  14. ^ Rojas, Raúl (7 de junio de 2014). "El Z1: arquitectura y algoritmos de la primera computadora de Konrad Zuse". arXiv : 1406.1886 [cs.AR].
  15. ^ ab Kahan, William Morton (15 de julio de 1997). "El nefasto efecto de los lenguajes informáticos y los puntos de referencia en las matemáticas, la física y la química aplicadas. Conferencia John von Neumann" (PDF) . pag. 3. Archivado (PDF) desde el 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.). Berlina; Nueva York: Springer-Verlag . pag. 244.ISBN _ 978-3-540-11319-5.
  17. ^ Indemnización, Charles (20 de febrero de 1998). "Una entrevista con el viejo del punto flotante".
  18. ^ ISO/IEC 9899:1999 - Lenguajes de programación - C. Iso.org. §F.2, nota 307."Extendido" es el formato de datos doblemente extendido de IEC 60559. Extendido se refiere a los formatos comunes IEC 60559 de 80 bits y cuádruple de 128 bits.
  19. ^ "Representación de punto flotante IEEE". 2021-08-03.
  20. ^ Uso de la colección de compiladores GNU, opciones i386 y x86-64 Archivado el 16 de enero de 2015 en Wayback Machine .
  21. ^ "doble largo (específico del CCG) y __float128". Desbordamiento de pila .
  22. ^ "Estándar de llamada de procedimiento para la arquitectura ARM de 64 bits (AArch64)" (PDF) . 2013-05-22. Archivado (PDF) desde el original el 31 de julio de 2013 . Consultado el 22 de septiembre de 2019 .
  23. ^ "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) desde el original el 27 de junio de 2015 . Consultado el 8 de noviembre de 2019 .
  24. ^ Kahan, William Morton (20 de noviembre de 2004). "Sobre el costo de la computación en punto flotante sin aritmética extraprecisa" (PDF) . Archivado (PDF) desde el original el 25 de mayo de 2006 . Consultado el 19 de febrero de 2012 .
  25. ^ "abrirEXR". abrirEXR . Consultado el 25 de abril de 2012 .
  26. ^ "Análisis IEEE-754".
  27. ^ ab personal de Borland (2 de julio de 1998) [10 de marzo de 1994]. "Conversión entre formatos Microsoft Binary e IEEE". Base de datos de información técnica (TI1431C.txt). Embarcadero USA / Inprise (originalmente: Borland ). ID 1400. Archivado desde el original el 2019-02-20 . Consultado el 30 de mayo de 2016 . […] _fmsbintoieee(float *src4, float *dest4) […] Formato binario 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 es sesgo 128 e IEEE tiene sesgo 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 128 y IEEE tiene un sesgo 1023. […] MBF coloca el punto decimal antes del bit asumido, mientras que IEEE coloca el punto decimal después del bit asumido. […] ieee_exp = msbin[7] - 128 - 1 + 1023; […]
  28. ^ ab Steil, Michael (20 de octubre de 2008). "Cree su propia versión de Microsoft BASIC para 6502". pagetable.com. Archivado desde el original el 30 de mayo de 2016 . Consultado el 30 de mayo de 2016 .
  29. ^ "IEEE frente a formato binario de Microsoft; problemas de redondeo (completo)". Soporte de Microsoft . Microsoft . 2006-11-21. ID de artículo KB35826, Q35826. Archivado desde el original el 28 de agosto de 2020 . Consultado el 24 de febrero de 2010 .
  30. ^ ab Kharya, Paresh (14 de mayo de 2020). "TensorFloat-32 en la GPU A100 acelera el entrenamiento de IA y HPC hasta 20 veces" . Consultado el 16 de mayo de 2020 .
  31. ^ "Arquitectura NVIDIA Hopper en profundidad". 2022-03-22.
  32. ^ Micikevicius, Paulius; Stosic, Dusan; Burgess, Neil; Córnea, Marius; Dubey, Pradeep; Grisenthwaite, Richard; Ja, Sangwon; Heinecke, Alejandro; Judd, Patricio; Kamalu, John; Melempudi, Naveen; Oberman, Estuardo; Shoeybi, Mohammad; Siu, Michael; Wu, Hao (12 de septiembre de 2022). "Formatos del FP8 para el aprendizaje profundo". arXiv : 2209.05433 [cs.LG].
  33. ^ Kahan, William Morton (11 de enero de 2006). "¿Cuán inútiles son las evaluaciones sin sentido del redondeo en la computación de punto flotante?" (PDF) . Archivado (PDF) desde el original el 21 de diciembre de 2004.
  34. ^ ab 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)
  35. ^ Loitsch, Florian (2010). "Imprimir números de punto flotante de forma rápida y precisa con números 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) desde el original el 29 de julio de 2014.
  36. ^ "Se agregó compatibilidad con el algoritmo Grisu3 para double.ToString(). Por mazong1123 · Solicitud de extracción n.° 14646 · dotnet/coreclr". GitHub .
  37. ^ Adams, Ulf (2 de diciembre de 2018). "Ryū: conversión rápida de flotador a cadena". Avisos ACM SIGPLAN . 53 (4): 270–282. doi : 10.1145/3296979.3192369 . S2CID  218472153.
  38. ^ Giulietti, Rafaello. "La forma Schubfach de renderizar dobles".
  39. ^ "abolz/Drachennest". GitHub . 2022-11-10.
  40. ^ "google/doble conversión". GitHub . 2020-09-21.
  41. ^ Lemire, Daniel (22 de marzo de 2021). "Análisis de números a un gigabyte por segundo". Software: práctica y experiencia . 51 (8): 1700-1727. arXiv : 2101.11408 . doi :10.1002/spe.2984. S2CID  231718830.
  42. ^ abc Goldberg, David (marzo de 1991). "Lo que todo informático debería saber sobre la aritmética de punto flotante" (PDF) . Encuestas de Computación ACM . 23 (1): 5–48. doi :10.1145/103162.103163. S2CID  222008826. Archivado (PDF) desde el original el 20 de julio de 2006 . Consultado el 20 de enero de 2016 .([2], [3], [4])
  43. ^ Patterson, David A.; Hennessy, John L. (2014). Organización y diseño de computadoras, la interfaz hardware/software . La serie de Morgan Kaufmann sobre arquitectura y diseño de computadoras (5ª ed.). Waltham, Massachusetts, Estados Unidos: Elsevier. pag. 793.ISBN _ 978-9-86605267-5.
  44. ^ ab Patente estadounidense 3037701A, Huberto M Sierra, "Medios de control aritmético de punto decimal flotante para calculadora", publicada el 5 de junio de 1962 
  45. ^ ab Kahan, William Morton (1 de octubre de 1997). "Notas de la conferencia sobre el estado del estándar IEEE 754 para aritmética binaria de coma flotante" (PDF) . pag. 9. Archivado (PDF) desde el original el 22 de junio de 2002.
  46. ^ "D.3.2.1". Manuales de desarrolladores de software de arquitecturas Intel 64 e IA-32 . vol. 1.
  47. ^ Harris, Richard (octubre de 2010). "¡Vas a tener que pensar!". Sobrecarga (99): 5–10. ISSN  1354-3172 . Consultado el 24 de septiembre de 2011 . Mucho más preocupante es el error de cancelación, que puede provocar una pérdida catastrófica de precisión.[5]
  48. ^ Christopher Barker: PEP 485: una función para probar la igualdad aproximada
  49. ^ "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.
  50. ^ Wilkinson, James Hardy (8 de septiembre de 2003). "Análisis de errores". En Ralston, Antonio; Reilly, Edwin D.; Hemmendinger, David (eds.). Enciclopedia de Ciencias de la Computación. Wiley . págs. 669–674. ISBN 978-0-470-86412-8. Consultado el 14 de mayo de 2013 .
  51. ^ Einarsson, Bo (2005). Precisión y confiabilidad en la computación científica. Sociedad de Matemática Industrial y Aplicada (SIAM). págs.50–. ISBN 978-0-89871-815-7. Consultado el 14 de mayo de 2013 .
  52. ^ abcd Higham, Nicholas John (2002). Precisión y estabilidad de algoritmos numéricos (2ª ed.). Sociedad de Matemática Industrial y Aplicada (SIAM). págs. 27–28, 110–123, 493. ISBN 978-0-89871-521-7. 0-89871-355-2.
  53. ^ Oliveira, Suely; Stewart, David E. (7 de septiembre de 2006). Redacción de software científico: una guía para el buen estilo. Prensa de la Universidad de Cambridge . págs.10–. ISBN 978-1-139-45862-7.
  54. ^ ab Kahan, William Morton (15 de julio de 2005). Aritmética de coma flotante asediada por "decisiones comerciales" (PDF) . ARITH 17 , simposio sobre aritmética informática patrocinado por IEEE (discurso de apertura). págs.6, 18. Archivado (PDF) desde el original el 17 de marzo de 2006 . Consultado el 23 de mayo de 2013 .(NB. Kahan estima que la incidencia de resultados excesivamente inexactos cerca de singularidades se reduce en un factor de aproximadamente 1/2000 utilizando los 11 bits adicionales de precisión de doble extensión ).
  55. ^ Kahan, William Morton (3 de agosto de 2011). Remedios desesperadamente necesarios para la imposibilidad de depuración de grandes cálculos de punto flotante en ciencia e ingeniería (PDF) . Conferencia de trabajo IFIP/SIAM/NIST sobre cuantificación de la incertidumbre en informática científica, Boulder, CO. p. 33. Archivado (PDF) desde el original el 20 de junio de 2013.
  56. ^ Kahan, William Morton ; Darcy, José (2001) [1 de marzo de 1998]. "Cómo el punto flotante de Java perjudica a todos en todas partes" (PDF) . Archivado (PDF) desde el original el 16 de agosto de 2000 . Consultado el 5 de septiembre de 2003 .
  57. ^ abcd Kahan, William Morton (27 de agosto de 2000). "Marketing versus Matemáticas" (PDF) . págs. 15, 35, 47. Archivado (PDF) desde el original el 15 de agosto de 2003.
  58. ^ Kahan, William Morton (12 de febrero de 1981). "¿Por qué necesitamos un estándar aritmético de punto flotante?" (PDF) . pag. 26. Archivado (PDF) desde el original el 4 de diciembre de 2004.
  59. ^ Kahan, William Morton (4 de junio de 2001). Bindel, David (ed.). "Apuntes de conferencias de soporte de sistemas para computación científica" (PDF) . Archivado (PDF) desde el original el 17 de mayo de 2013.
  60. ^ "Aritmética decimal general". Speleotrove.com . Consultado el 25 de abril de 2012 .
  61. ^ Christiansen, Tom; Torkington, Nathan; et al. (2006). "perlfaq4 / ¿Por qué está roto int()?". perldoc.perl.org . Consultado el 11 de enero de 2011 .
  62. ^ Shewchuk, Jonathan Richard (1997). "Aritmética de coma flotante de precisión adaptativa y predicados geométricos rápidos y robustos". Geometría discreta y computacional . 18 (3): 305–363. doi : 10.1007/PL00009321 .
  63. ^ Kahan, William Morton ; Marfil, Melody Y. (3 de julio de 1997). "El redondeo degrada un voladizo idealizado" (PDF) . Archivado (PDF) desde el original el 5 de diciembre de 2003.
  64. ^ "Autovectorización en LLVM". Documentación LLVM 13 . Admitimos operaciones de reducción de punto flotante cuando se utiliza -ffast-math.
  65. ^ "Matemáticas de punto flotante". Wiki del CCG .
  66. ^ "55522 – -funsafe-math-optimizations es inesperadamente dañino, especialmente con -shared". gcc.gnu.org .
  67. ^ "Opciones de generación de código (el compilador GNU Fortran)". gcc.gnu.org .
  68. ^ "Error en zheevd · Número 43 · Referencia-LAPACK/lapack". GitHub .
  69. ^ Becker, Heiko; Darulova, Eva; Myreen, Magnus O.; Tatlock, Zachary (2019). "Icing: compatibilidad con optimizaciones de estilo Fast-Math en un compilador verificado ". CAV 2019: Verificación Asistida por Computadora. vol. 11562. págs. 155-173. doi : 10.1007/978-3-030-25543-5_10 .

Otras lecturas

enlaces externos