En informática , la aritmética de punto flotante ( FP ) es una aritmética que representa subconjuntos de números reales utilizando un entero con una precisión fija, llamado mantisa , escalado por un exponente entero de una base fija. Los números de esta forma se denominan 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, sino que necesita seis dígitos de precisión; el número de punto flotante más cercano con solo cinco dígitos es 12.346. En la práctica, la mayoría de los sistemas de punto flotante utilizan la base dos , aunque la base diez ( punto 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 base diez de precisión, 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 el punto de la base del número puede "flotar" en cualquier lugar hacia la izquierda, la derecha o entre los dígitos significativos del número. Esta posición se indica mediante el exponente, por lo que el punto flotante puede considerarse una forma de notación científica .
Un sistema de coma flotante puede utilizarse 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 coma 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]


A lo largo de los años, se han utilizado en las computadoras diversas 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ñada 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, generalmente como una cadena de dígitos.
Existen varios mecanismos mediante los cuales las cadenas de dígitos pueden representar números. En la notación matemática estándar, la cadena de dígitos puede tener cualquier longitud y la ubicación del punto decimal se indica colocando allí un carácter de "punto" explícito (punto o coma). Si no se especifica el punto decimal, la cadena representa implícitamente un número entero y el punto decimal no especificado estaría fuera del 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 decimal. 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, por lo que "00012345" representaría 0001,2345.
En notación científica , el número dado se escala mediante una potencia de 10 , de modo que se encuentre dentro de un rango específico, generalmente entre 1 y 10, con el punto de la base que 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 Ío de Júpiter es152.853,5047 segundos, un valor que se representaría en notación científica de forma estándar como1.528535047 × 10 5 segundos.
La representación en punto flotante es similar en concepto a la notación científica. Lógicamente, un número en punto flotante consta de:
- Cadena de dígitos con signo (que significa positivo o negativo) de una longitud dada en una base (o radix ) dada. Esta cadena de dígitos se conoce como mantisa , 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 la base siempre está en algún lugar dentro de la mantisa, a menudo 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 generalmente sigue la convención de que el punto de la base se establece justo después del dígito más significativo (más a la izquierda).
- Un exponente entero con signo (también denominado característico o escala ), [nb 2] que modifica la magnitud del número.
Para derivar 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 de la base desde su posición implícita por 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 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 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 de la mantisa 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 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 equilibrado [1] ) e incluso la base 256 [5] [nb 6] y la base65.536 . [8] [n.º 7]
Un número de punto flotante es un número racional , porque se puede representar como un 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 utilizando una base binaria, pero 1/5 se puede representar exactamente utilizando una base decimal (0,2 , o2 × 10 −1 ). Sin embargo, 1/3 no se puede representar 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 las que se producen expansiones infinitas dependen de la base y de sus factores primos .
La forma en que se almacenan la mantisa (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), , y por lo tanto, la mantisa es una cadena de 24 bits . Por ejemplo, los primeros 33 bits del número π son:
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). El bit significativo 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 o bit 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 valores intermedios , lo que no es el caso aquí). Este bit, que esEn este ejemplo, se suma 1 al entero formado por los 24 bits más a la izquierda, lo que da como resultado:
Cuando esto se almacena en la memoria utilizando la codificación IEEE 754, se convierte en el mantisa s . Se supone que el 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:
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).
Se puede requerir 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 llama 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 representarse en la memoria, lo que permite 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 oculta [1] o convención de bits asumidos .
Alternativas a los números de punto flotante
La representación en coma flotante es, con diferencia, la forma más habitual de representar en ordenadores 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 de una convención específica sobre la ubicación del punto binario o decimal, por ejemplo, 6 bits o dígitos desde la derecha. El hardware para manipular estas representaciones es menos costoso que el de punto flotante y también se puede utilizar para realizar operaciones normales con números enteros. El punto fijo binario se utiliza generalmente en aplicaciones especiales en procesadores integrados que solo pueden realizar aritmética con números enteros, pero el punto fijo decimal es común en aplicaciones comerciales.
- Los sistemas de numeración logarítmica (LNS) 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 del punto flotante, pero la curva valor-representación ( es decir , el gráfico de la función logarítmica) es suave (excepto en 0). A la inversa de la aritmética de punto flotante, en un sistema de numeración logarítmico 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 ( simétrica ) (LI y SLI) 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ónico , que no parece utilizarse en la práctica.
- Algunos números racionales simples ( por ejemplo , 1/3 y 1/10) no se pueden representar exactamente en coma flotante binaria, sin importar cuál sea la precisión. El uso de un radio diferente permite representar algunos de ellos ( por ejemplo , 1/10 en coma flotante decimal), pero las posibilidades siguen siendo limitadas. Los paquetes de software que realizan aritmética racional representan números como fracciones con numerador y denominador enteros y, por lo tanto, pueden representar cualquier número racional exactamente. Dichos paquetes generalmente necesitan usar la aritmética " bignum " para los números enteros individuales.
- La aritmética de intervalos permite representar números como intervalos y obtener límites garantizados para los resultados. Generalmente se basa en otras operaciones aritméticas, en particular en la de punto flotante.
- Los sistemas de álgebra computacional como Mathematica , Maxima y Maple a menudo pueden manejar números irracionales como o de una manera completamente "formal" ( computación simbólica ), sin tener que lidiar con una codificación específica del mantisa. Un programa de este tipo puede evaluar expresiones como " " con exactitud, porque está programado para procesar las matemáticas subyacentes directamente, en lugar de usar valores aproximados para cada cálculo intermedio.
Historia

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 la manipulación consistente de números de punto flotante por parte de 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 mantra de tamaño fijo como el que se usa actualmente para datos de punto flotante, fijando la ubicación del punto decimal en el mantra para que cada representación fuera única, y cómo formatear dichos números especificando una sintaxis a usar que pudiera ser ingresada a través de una máquina de escribir , como fue el caso de su Aritmómetro Electromecánico en 1920. [10] [11] [12]
.jpg/500px-Konrad_Zuse_(1992).jpg)
En 1938, Konrad Zuse de Berlín completó la Z1 , la primera computadora mecánica binaria programable ; [13] utiliza una representación numérica de punto flotante binario de 24 bits con un exponente con signo de 7 bits, un mantisa de 17 bits (incluido un bit implícito) y un bit de signo. [14] La Z3 basada en relés más confiable , completada en 1941, tiene representaciones tanto para infinitos positivos como 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 de NaN, anticipándose en cuatro décadas a las características del estándar IEEE. [15] Por el contrario, von Neumann recomendó no utilizar 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 implementó números decimales de punto flotante . [16]
El Pilot ACE tiene aritmética binaria de punto flotante y comenzó a funcionar en 1950 en el Laboratorio Nacional de Física del Reino Unido . Más tarde se vendieron treinta y tres unidades en el mercado con el nombre de English Electric DEUCE . La aritmética está implementada en software, pero con una frecuencia de reloj de un megahercio, la velocidad de las operaciones de punto flotante y punto fijo en esta máquina era inicialmente más rápida que la de muchas computadoras de la competencia.
En 1954 se produjo en serie el IBM 704 , que introdujo el uso de un exponente sesgado . Durante muchas décadas después, el hardware de punto flotante era una característica opcional y se decía que los ordenadores que lo tenían eran "ordenadores científicos" o que tenían capacidad de " computación científica " (SC) (véase también Extensiones para computación científica (XSC)). No fue hasta el lanzamiento del Intel i486 en 1989 que los ordenadores personales de uso general tuvieron capacidad de punto flotante en el hardware como una característica estándar.
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 un significando de 27 bits.
- Doble precisión : 72 bits, organizados como un signo de 1 bit, un exponente de 11 bits y un significando 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 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 los sistemas z/Architecture modernos . En 1998, IBM implementó aritmética de punto flotante binario compatible con IEEE en sus mainframes; en 2005, IBM también agregó aritmética de punto flotante decimal compatible con IEEE.
Inicialmente, las computadoras utilizaban 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 los tamaños de palabra, 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 en la misma época, también realizó importantes aportes.

En 1989, el matemático y científico informático William Kahan fue honrado con el Premio Turing por ser el arquitecto principal detrás de esta propuesta; fue ayudado por su estudiante Jerome Coonen y un profesor visitante, Harold Stone . [17]
Entre las innovaciones del x86 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 un ordenador a otro de forma precisa y eficiente (después de tener en cuenta el orden de bytes ).
- Un comportamiento especificado con precisión para las operaciones aritméticas: se requiere que se produzca un resultado como si se utilizara una aritmética infinitamente precisa para obtener un valor que luego se redondea de acuerdo con reglas específicas. Esto significa que un programa informático compatible siempre produciría el mismo resultado cuando se le diera una entrada particular, mitigando así la reputación casi mística que se había ganado el cálculo de punto flotante por su comportamiento aparentemente no determinista hasta entonces.
- 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 manera controlada.
Rango de números de punto flotante
Un número de coma flotante consta 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 coma flotante depende linealmente del rango de la mantisa y exponencialmente del rango del componente exponente, lo que otorga al número un rango notablemente más amplio.
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. Como 2 10 = 1024, el rango completo de los 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 de punto flotante normales en un sistema ( B , P , L , U ) donde
- B es la base del sistema,
- P es la precisión del mantisa (en base B ),
- L es el exponente más pequeño del sistema,
- U es el mayor exponente del sistema,
es .
Existe un número de punto flotante normal positivo más pequeño,
- Nivel de subsuelo = UFL = ,
que tiene un 1 como dígito principal y 0 para los dígitos restantes del mantis, 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 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: punto flotante en las computadoras modernas
El IEEE estandarizó la representación informática de los números binarios de coma flotante en IEEE 754 (también conocido como IEC 60559) en 1985. Este primer estándar es seguido por casi todas las máquinas modernas. Fue revisado 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 tenía una versión IEEE, pero el SV1 todavía utiliza el formato de coma flotante Cray. [ cita requerida ]
El estándar prevé muchos formatos estrechamente relacionados, que difieren solo en unos pocos detalles. Cinco de estos formatos se denominan formatos básicos y otros se denominan formatos de precisión extendida y formatos de precisión extensible . Tres formatos se utilizan especialmente en hardware y lenguajes informáticos: [ cita requerida ]
- Precisión simple (binary32), generalmente utilizada para representar el tipo "float" en la familia de lenguajes C. Se trata de un formato binario que ocupa 32 bits (4 bytes) y su mantisa tiene una precisión de 24 bits (unos 7 dígitos decimales).
- Doble precisión (binary64), generalmente utilizado para representar el tipo "double" en la familia de lenguajes C. Se trata de un formato binario que ocupa 64 bits (8 bytes) y su mantisa tiene una precisión de 53 bits (unos 16 dígitos decimales).
- Formato doble extendido , también llamado ambiguamente "de precisión extendida". Se trata de un formato binario que ocupa al menos 79 bits (80 si no se utiliza la regla de bits ocultos/implícitos) y su mantisa tiene una precisión de al menos 64 bits (unos 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 se proporcione un formato extendido de este tipo llamado " doble largo ". [18] La arquitectura x86 proporciona 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) . A menudo, en dichos procesadores, este formato se puede utilizar con "doble largo", aunque la precisión extendida no está disponible con MSVC. [19] Para fines de alineación , muchas herramientas almacenan este valor de 80 bits en un espacio de 96 o 128 bits. [20] [21] En otros procesadores, "doble largo" puede representar un formato más grande, como precisión cuádruple, [22] o simplemente precisión doble, si no está disponible ninguna forma de precisión extendida. [23]
Aumentar la precisión de la representación de punto flotante generalmente reduce la cantidad de error de redondeo acumulado causado por cálculos intermedios. [24] Otros formatos IEEE incluyen:
- Formatos de punto flotante decimal64 y decimal128 . Estos formatos (especialmente el decimal128) son muy utilizados en las transacciones financieras porque, junto con el formato decimal32 , permiten un redondeo decimal correcto.
- Precisión cuádruple (binary128). Se trata de un formato binario que ocupa 128 bits (16 bytes) y su mantisa tiene una precisión de 113 bits (unos 34 dígitos decimales).
- Precisión media , también llamada binary16, un valor de punto flotante de 16 bits. Se utiliza en el lenguaje de gráficos NVIDIA Cg y en el estándar openEXR (donde, de hecho, es anterior a su introducción en el estándar IEEE 754). [25] [26]
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 precisión doble. Además, se puede representar una amplia gama de potencias de 2 veces dicho número. Estas propiedades se utilizan a veces para datos puramente enteros, para obtener números enteros de 53 bits en plataformas que tienen números flotantes de precisión doble pero solo números 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 "que no son un número" ( NaNs ).
La comparación de números de punto flotante, tal como se define en el estándar IEEE, es un poco diferente de la comparación de números enteros habitual. Los ceros negativos y positivos se comparan como iguales, y cada NaN se compara como desigual con cada valor, incluido él mismo. Todos los números de punto flotante finitos son estrictamente menores que +∞ y estrictamente mayores que −∞ , y están ordenados de la misma manera que sus valores (en el conjunto de números reales).
Representación interna
Los números de punto flotante se suelen incluir en un dato informático como bit de signo, campo de exponente y 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 0 en este campo se reservan para los ceros y los números subnormales ; los valores de todos los 1 se reservan para los infinitos y los NaN. El rango del exponente para los 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 los valores subnormales, los ceros, los infinitos y los NaN.
En los formatos de intercambio binario IEEE, el bit inicial de un mantis normalizado no se almacena en los datos informáticos. Se lo denomina bit "oculto" o "implícito". Por este motivo, el formato de precisión simple tiene un mantis con 24 bits de precisión, el formato de precisión doble tiene 53 y el cuádruple tiene 113.
Por ejemplo, se demostró anteriormente que π, redondeado a 24 bits de precisión, tiene:
- signo = 0; e = 1; s = 110010010000111111011011 (incluido el bit oculto)
La suma del sesgo del exponente (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 [27] como un número hexadecimal .
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 ciertas áreas específicas del dominio.
- El formato binario de Microsoft (MBF) fue desarrollado para los productos de lenguaje BASIC de Microsoft, 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 anterior a la versión 4.00. Las versiones 4.00 y 4.50 de QuickBASIC 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 , un compañero de dormitorio 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 de variante de precisión simple (40 bits) para otras CPU, en particular la MOS 6502 ( Apple // , 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 usaron el formato binario de Microsoft hasta que Microsoft adoptó el formato estándar IEEE-754 en todos sus productos a partir de 1988 hasta sus lanzamientos actuales. MBF consta del formato MBF de precisión simple (32 bits, "BASIC de 6 dígitos"), [28] [29] el formato MBF de precisión extendida (40 bits, "BASIC de 9 dígitos"), [29] y el formato MBF de doble precisión (64 bits); [28] [30] cada uno de ellos se representa con un exponente de 8 bits, seguido de un bit de signo, seguido de un significado de respectivamente 23, 31 y 55 bits.
- El formato Bfloat16 requiere la misma cantidad de memoria (16 bits) que el formato IEEE 754 de media precisión , pero asigna 8 bits al exponente en lugar de 5, lo que proporciona el mismo rango que un número IEEE 754 de precisión simple . La contrapartida es una precisión reducida, ya que el campo de 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 proporcionan soporte de hardware para este formato.
- El formato TensorFloat-32 [31] 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 da como resultado un tamaño de 19 bits. Este formato fue introducido por Nvidia , que proporciona soporte de hardware para él en los núcleos Tensor de sus GPU basadas en la arquitectura Ampere de Nvidia. El inconveniente 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 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. [31]
- Las GPU de arquitectura Hopper proporcionan dos formatos FP8: uno con el mismo rango numérico que la media precisión (E5M2) y otro con mayor precisión, pero menor rango (E4M3). [32] [33]
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). Los números irracionales, como π o √2, o los números racionales no terminales, deben aproximarse. El número de dígitos (o bits) de precisión también limita el conjunto de números racionales que se pueden representar exactamente. Por ejemplo, el número decimal 123456789 no se puede representar 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 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 compatible con una implementación informática, será necesaria una conversión antes de poder usarse en esa implementación. Si el número se puede representar exactamente en el formato de punto flotante, la conversión es exacta. Si no hay una representación exacta, la conversión requiere la elección de qué número de punto flotante se usará para representar el valor original. La representación elegida tendrá un valor diferente del original, y el valor así ajustado se denomina valor redondeado .
El hecho de que un número racional tenga o no una expansión 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 la tiene (0,333...). En base 2, solo los racionales con denominadores que sean potencias de 2 (como 1/2 o 3/16) son terminales. 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 una aproximación cuando se convierten a punto flotante binario. Por ejemplo, el número decimal 0,1 no es representable en punto flotante binario de ninguna precisión finita; la representación binaria exacta tendría una secuencia "1100" que continuaría sin fin:
- mi = −4; s = 1100110011001100110011001100110011...,
donde, como anteriormente, s es el significando 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 valor verdadero 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 é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 el último lugar (ULP). Por ejemplo, si no hay ningún número representable que se encuentre entre los números representables 1.45a70c22 hex y 1.45a70c24 hex , la ULP es 2×16 −8 , o 2 −31 . Para los números con una parte del exponente de base 2 de 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 que hay en el mantisa. IEEE 754 requiere un redondeo correcto : es decir, el resultado redondeado es como si se hubiera utilizado una aritmética infinitamente precisa para calcular el valor y luego se hubiera redondeado (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) se usa con más frecuencia. 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 el caso de un empate, se elige el valor que haría que el mantisa termine en un dígito par. El estándar IEEE 754 exige que se aplique el mismo redondeo a todas las operaciones algebraicas fundamentales, incluidas las raíces cuadradas y las conversiones, cuando hay un resultado numérico (no 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 NaN. (Las funciones "de biblioteca", como coseno y logaritmo, no son obligatorias).
También hay opciones de redondeo alternativas disponibles. IEEE 754 especifica los siguientes modos de redondeo:
- redondear al más cercano, donde redondea al dígito par más cercano en la posición requerida (el modo predeterminado y, por lejos, el más común)
- redondear al más cercano, donde los empates se redondean alejándose de cero (opcional para punto flotante binario y comúnmente usado en decimal)
- redondear hacia arriba (hacia +∞; los resultados negativos se redondean hacia cero)
- redondear hacia abajo (hacia −∞; los resultados negativos se redondean alejándose de cero)
- redondear hacia cero (truncamiento; es similar al comportamiento común de las conversiones de flotante a entero, que convierten −3,9 en −3 y 3,9 en 3)
Los modos alternativos son útiles cuando se debe limitar la cantidad de error que se introduce. Las aplicaciones que requieren un error limitado son los cálculos 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 un error de redondeo. [34]
Conversión de binario a decimal con un número mínimo de dígitos
La conversión de 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 produjera resultados que fueran precisos y mínimos 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. [35]
- Grisu3, con una aceleración de 4x, ya que elimina el uso de números grandes . Debe utilizarse con una alternativa, ya que falla en aproximadamente el 0,5 % de los casos. [36]
- Errol3, un algoritmo que siempre funciona bien, similar a Grisu3, pero más lento. Aparentemente no es tan bueno como un Grisu de terminación temprana con respaldo. [37]
- Ryū, un algoritmo que siempre tiene éxito y que es más rápido y simple que Grisu3. [38]
- Schubfach, un algoritmo que siempre tiene éxito y que se basa en una idea similar a Ryū, desarrollado casi simultáneamente e independientemente. [39] Tiene un mejor rendimiento que Ryū y Grisu3 en ciertos puntos de referencia. [40]
Muchos entornos de ejecución de lenguajes modernos utilizan Grisu3 con un respaldo de Dragon4. [41]
Conversión de decimal a binario
El problema de analizar una cadena decimal para obtener una representación binaria de FP es complejo, y no fue hasta el trabajo de Clinger de 1990 (implementado en dtoa.c) que apareció un analizador preciso. [35] Asimismo, se han realizado trabajos posteriores en la dirección de un análisis más rápido. [42]
Operaciones de punto flotante
Para facilitar la presentación y la comprensión, en los ejemplos se utilizará un sistema decimal con una precisión de 7 dígitos, como en el formato IEEE 754 decimal32 . Los principios fundamentales son los mismos en cualquier sistema decimal o precisión, excepto que la normalización es opcional (no afecta el valor numérico del resultado). Aquí, s denota la mantisa y e denota el exponente.
Suma y resta
Un método sencillo para sumar números de punto flotante es representarlos primero con el mismo exponente. En el ejemplo siguiente, el segundo número se desplaza 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) + e=2; s=1,017654 (101,7654)
e=5; s=1,234567 + e=5; s=0,001017654 (después del cambio) -------------------- e=5; s=1,235584654 (suma verdadera: 123558,4654)
Este es el resultado real, la suma exacta de los operandos. Se redondeará a 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) se pierden esencialmente. Esto es un error de redondeo . En casos extremos, la suma de dos números distintos de cero puede ser igual a uno de ellos:
e=5; s=1,234567 + e=−3; s=9,876543
e=5; s=1,234567 + e=5; s=0,00000009876543 (después del cambio) ---------------------- e=5; s=1,23456709876543 (suma verdadera) e=5; s=1,234567 (después del redondeo y la normalización)
En los ejemplos conceptuales anteriores, parecería que el sumador debería proporcionar una gran cantidad de dígitos adicionales para garantizar un redondeo correcto; sin embargo, para la suma o resta binaria que utiliza técnicas de implementación cuidadosas, solo es necesario llevar un bit de protección , un bit de redondeo y un bit fijo adicional más allá de la precisión de los operandos. [43] [44] : 218–220
Otro problema de pérdida de significancia ocurre cuando se restan las aproximaciones a dos números casi iguales. En el siguiente ejemplo, e = 5; s = 1,234571 y e = 5; s = 1,234567 son aproximaciones a los racionales 123457,1467 y 123456,659.
e=5; s=1,234571 − e=5; s=1,234567 ---------------- e=5; s=0,000004 e=−1; s=4,000000 (después del redondeo y la normalización)
La diferencia de punto flotante se calcula exactamente porque los números son cercanos: el lema de Sterbenz garantiza esto, incluso en caso de desbordamiento por defecto cuando se admite el desbordamiento por defecto gradual . A pesar de esto, la diferencia de los números originales es e = −1; s = 4.877000, que difiere más del 20% de la diferencia e = −1; s = 4.000000 de las aproximaciones. En casos extremos, se pueden perder todos los dígitos significativos de precisión. [43] [45] Esta cancelación ilustra el peligro de suponer que todos los dígitos de un resultado calculado son significativos. El tratamiento de las consecuencias de estos errores es un tema del análisis numérico ; consulte también Problemas de precisión.
Multiplicación y división
Para multiplicar, se multiplican los mantis 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 logra restando el exponente del divisor del exponente del dividendo y dividiendo el mantisa del dividendo por el mantisa del divisor.
No existen problemas de cancelación o absorción con la multiplicación o división, aunque pueden acumularse pequeños errores a medida que se realizan operaciones en sucesión. [43] En la práctica, la forma en que se llevan a cabo estas operaciones en la lógica digital puede ser bastante compleja (ver 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 de los lenguajes. Normalmente utilizan 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 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:
99.9-5000.126.02e23-3e-450x1.fffffep+127en C y IEEE 754
Cómo afrontar casos excepcionales
El cálculo de punto flotante en una computadora puede generar tres tipos de problemas:
- Una operación puede ser matemáticamente indefinida, como ∞/∞, o una división por cero .
- Una operación puede ser legal en principio, pero no estar admitida 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 de exponente. Este tipo de evento se denomina desbordamiento (exponente demasiado grande), desbordamiento insuficiente (exponente demasiado pequeño) o desnormalización (pérdida de precisión).
Antes de la norma IEEE, estas condiciones solían provocar la finalización del programa o desencadenar algún tipo de trampa que el programador podía detectar. La forma en que esto funcionaba dependía del sistema, lo que significa que los programas de punto flotante no eran portables . (El término "excepción" tal como se utiliza 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 los que una " excepción " es un flujo alternativo de control, más cercano a lo que se denomina una "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 el atrapamiento opcional IEEE 754 ni otros modos de "manejo de excepciones alternativo"). Las excepciones aritméticas (por defecto) deben registrarse en bits de bandera de estado "pegajosos". Que sean "pegajosos" 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 banderas "pegajosas" permite, por tanto, retrasar la prueba de condiciones excepcionales hasta después de una expresión o subrutina de punto flotante completa: sin ellas, las condiciones excepcionales que no podrían ignorarse de otro modo requerirían una prueba 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 +∞, mientras que también establece el bit de bandera 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, se puede ignorar de forma segura).
Sin embargo, el estándar IEEE 754 original no recomendaba operaciones para manejar estos conjuntos de bits de indicadores de excepción aritmética. Por lo tanto, si bien estos se implementaron en hardware, inicialmente las implementaciones de lenguaje de programación generalmente no proporcionaban un medio para acceder a ellos (aparte del ensamblador). Con el tiempo, algunos estándares de lenguaje 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 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 solo hilo de ejecución y el uso de ellos por parte de múltiples hilos debe manejarse por un medio fuera del estándar (por ejemplo, C11 especifica que los indicadores tienen almacenamiento local del hilo ).
IEEE 754 especifica cinco excepciones aritméticas que deben registrarse en los indicadores de estado ("bits fijos"):
- inexacto , se establece si el valor redondeado (y devuelto) es diferente del resultado matemáticamente exacto de la operación.
- desbordamiento inferior , se establece si el valor redondeado es minúsculo (como se especifica en IEEE 754) e inexacto (o tal vez limitado a si tiene pérdida de desnormalización, según la versión de 1985 de IEEE 754), y devuelve un valor subnormal que incluye los ceros.
- desbordamiento , se establece si el valor absoluto del valor redondeado es demasiado grande para ser representado. Se devuelve un valor infinito o finito máximo, según el redondeo que se utilice.
- dividir por cero , se establece si el resultado es infinito dados operandos finitos, y devuelve un infinito, ya sea +∞ o −∞.
- no válido , se establece si no se puede devolver un resultado de valor real, por ejemplo, sqrt(−1) o 0/0, que devuelve un NaN silencioso.

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. [46] divide-por-cero devuelve infinito exactamente, lo que normalmente dividirá un número finito y dará cero, o bien dará una excepción no válida posteriormente si no, y por lo tanto también se puede ignorar normalmente. Por ejemplo, la resistencia efectiva de n resistencias en paralelo (ver fig. 1) está dada por . Si se desarrolla un cortocircuito con establecido en 0, devolverá +infinito que dará un final de 0, como se esperaba [47] (ver el ejemplo de fracción continua de la justificación del diseño IEEE 754 para otro ejemplo).
Por lo general, no se pueden ignorar los desbordamientos y las excepciones no válidas , pero no necesariamente representan errores: por ejemplo, una rutina de búsqueda de raíces , como parte de su funcionamiento normal, puede evaluar una función pasada en valores fuera de su dominio, devolviendo NaN y un indicador de excepción no válida que se debe ignorar hasta encontrar un punto de inicio útil. [46]
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 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 IEEE 754 binary32 con su mantíndiz 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
Elevando este número al cuadrado obtenemos
Al elevarlo al cuadrado y redondearlo a la precisión de 24 bits se obtiene
Pero el número representable más cercano a 0,01 es
Además, la no representabilidad de π (y π/2) significa que un intento de cálculo de tan(π/2) no arrojará un resultado de 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 de punto flotante estándar intente calcular tan(π/2), porque π/2 no se puede representar con exactitud. Este cálculo en C:
/* Suficientes dígitos para asegurarnos de que obtenemos la aproximación correcta. */
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.
De la misma manera, un intento de cálculo de sin(π) no dará como resultado cero. El resultado será (aproximadamente) 0,1225 × 10 −15 en precisión doble, o −0,8742 × 10 −7 en precisión simple. [nb 10]
Si bien la suma y la multiplicación en coma flotante son ambas 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 la 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 significancia, la incapacidad de representar con exactitud números como π y 0,1 y otras ligeras 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, fijamos los dígitos más significativos en cero, quedándonos sólo 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:
Intuitivamente, uno querría un valor h muy cercano a cero; sin embargo, al utilizar operaciones de punto flotante, el número más pequeño no dará la mejor aproximación de una derivada. A medida que h se hace más pequeño, la diferencia entre f ( a + h ) y f ( a ) se hace más pequeña, cancelando los dígitos más significativos y menos erróneos y haciendo que los dígitos más erróneos sean más importantes. Como resultado, el número más pequeño de h posible dará una aproximación más errónea de una derivada que un número algo mayor. Este es quizás el problema de precisión más común y serio. - Las conversiones a números enteros no son intuitivas: convertir (63,0/9,0) a números enteros 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 respuestas que se desvían en un valor del valor esperado intuitivamente.
- Rango de exponentes limitado: los resultados pueden desbordarse y dar como resultado infinito, o desbordarse por debajo de lo normal y dar como resultado un número inferior al normal o cero. En estos casos, se perderá precisión.
- Probar una división segura es problemático: verificar que el divisor no sea cero no garantiza que una división no se desborde.
- La comprobación de la igualdad es problemática. Dos secuencias computacionales que son matemáticamente iguales pueden producir valores de punto flotante diferentes. [49]
Incidentes
- El 25 de febrero de 1991, una pérdida de importancia en una batería de misiles MIM-104 Patriot le impidió interceptar un misil Scud entrante en Dhahran , Arabia Saudita , lo que contribuyó a la muerte de 28 soldados del 14º Destacamento de Intendencia del Ejército de los EE. UU . [50]
Análisis de precisión de la máquina y de errores hacia atrás
La precisión de la máquina es una cantidad que caracteriza la exactitud 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 conoce como redondeo unitario o épsilon de máquina . Generalmente se denota como Ε mach y su valor depende del redondeo particular que se utilice.
Con redondeo a cero, mientras que redondeo al más cercano, donde B es la base del sistema y P es la precisión del mantisa (en base B ).
Esto es importante porque 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. [51] El enfoque básico es mostrar que, aunque el resultado calculado, debido a los 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. [52]
Como ejemplo trivial, considere una expresión simple que da el producto interno de los vectores (de longitud dos) y , entonces y por lo tanto
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 [53] 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 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 (scratch) en un algoritmo con una precisión mayor que la que requiere el resultado final, [54] lo que puede eliminar o reducir en órdenes de magnitud [55] 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 precisión doble. [56] [nb 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, se puede demostrar que es numéricamente inestable y pierde hasta la mitad de los dígitos significativos transportados por la aritmética cuando se calcula cerca de 1.0. [57]
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]
devuelve Z ;
}
Sin embargo, si todos los cálculos intermedios se realizan con precisión extendida (por ejemplo, estableciendo la línea [1] en C99 long double ), entonces se puede mantener hasta la precisión completa 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 = logaritmo ( Z ) / ( Z - 1,0 );
then the algorithm becomes numerically stable and can compute to full double precision.
To maintain the properties of such carefully constructed numerically stable programs, careful handling by the compiler is required. Certain "optimizations" that compilers might make (for example, reordering operations) can work against the goals of well-behaved software. There is some controversy about the failings of compilers and language designs in this area: C99 is an example of a language where such optimizations are carefully specified to maintain numerical precision. See the external references at the bottom of this article.
A detailed treatment of the techniques for writing high-quality floating-point software is beyond the scope of this article, and the reader is referred to,[53][58] and the other references at the bottom of this article. Kahan suggests several rules of thumb that can substantially decrease by orders of magnitude[58] the risk of numerical anomalies, in addition to, or in lieu of, a more careful numerical analysis. These include: as noted above, computing all expressions and intermediate results in the highest precision supported in hardware (a common rule of thumb is to carry twice the precision of the desired result, i.e. compute in double precision for a final single-precision result, or in double extended or quad precision for up to double-precision results[59]); and rounding input data and results to only the precision required and supported by the input data (carrying excess precision in the final result beyond that required and supported by the input data can be misleading, increases storage cost and decreases speed, and the excess bits can affect convergence of numerical procedures:[60] notably, the first form of the iterative example given below converges correctly when using this rule of thumb). Brief descriptions of several additional issues and techniques follow.
As decimal fractions can often not be exactly represented in binary floating-point, such arithmetic is at its best when it is simply being used to measure real-world quantities over a wide range of scales (such as the orbital period of a moon around Saturn or the mass of a proton), and at its worst when it is expected to model the interactions of quantities expressed as decimal strings that are expected to be exact.[55][58] An example of the latter case is financial calculations. For this reason, financial software tends not to use a binary floating-point number representation.[61] The "decimal" data type of the C# and Python programming languages, and the decimal formats of the IEEE 754-2008 standard, are designed to avoid the problems of binary floating-point representations when applied to human-entered exact decimal values, and make the arithmetic always behave as expected when numbers are printed in decimal.
Expectations from mathematics may not be realized in the field of floating-point computation. For example, it is known that , and that , however these facts cannot be relied on when the quantities involved are the result of floating-point computation.
The use of the equality test (if (x==y) ...) requires care when dealing with floating-point numbers. Even simple expressions like 0.6/0.2-3==0 will, on most computers, fail to be true[62] (in IEEE 754 double precision, for example, 0.6/0.2 - 3 is approximately equal to -4.44089209850063e-16). Consequently, such tests are sometimes replaced with "fuzzy" comparisons (if (abs(x-y) < epsilon) ..., where epsilon is sufficiently small and tailored to the application, such as 1.0E−13). The wisdom of doing this varies greatly, and can require numerical analysis to bound epsilon.[53] Values derived from the primary data representation and their comparisons should be performed in a wider, extended, precision to minimize the risk of such inconsistencies due to round-off errors.[58] It is often better to organize the code in such a way that such tests are unnecessary. For example, in computational geometry, exact tests of whether a point lies off or on a line or plane defined by other points can be performed using adaptive precision or exact arithmetic methods.[63]
Small errors in floating-point arithmetic can grow when mathematical algorithms perform operations an enormous number of times. A few examples are matrix inversion, eigenvector computation, and differential equation solving. These algorithms must be very carefully designed, using numerical approaches such as iterative refinement, if they are to work well.[64]
Summation of a vector of floating-point values is a basic algorithm in scientific computing, and so an awareness of when loss of significance can occur is essential. For example, if one is adding a very large number of numbers, the individual addends are very small compared with the sum. This can lead to loss of significance. A typical addition would then be something like
3253.671 + 3.141276 ----------- 3256.812
The low 3 digits of the addends are effectively lost. Suppose, for example, that one needs to add many numbers, all approximately equal to 3. After 1000 of them have been added, the running sum is about 3000; the lost digits are not regained. The Kahan summation algorithm may be used to reduce the errors.[53]
Round-off error can affect the convergence and accuracy of iterative numerical procedures. As an example, Archimedes approximated π by calculating the perimeters of polygons inscribing and circumscribing a circle, starting with hexagons, and successively doubling the number of sides. As noted above, computations may be rearranged in a way that is mathematically equivalent but less prone to error (numerical analysis). Two forms of the recurrence formula for the circumscribed polygon are:[citation needed]
- First form:
- second form:
- , converging as
Here is a computation using IEEE "double" (a significand with 53 bits of precision) arithmetic:
i 6 × 2i × ti, first form 6 × 2i × ti, second form --------------------------------------------------------- 0 3.4641016151377543863 3.4641016151377543863 1 3.2153903091734710173 3.2153903091734723496 2 3.1596599420974940120 3.1596599420975006733 3 3.1460862151314012979 3.1460862151314352708 4 3.1427145996453136334 3.1427145996453689225 5 3.1418730499801259536 3.1418730499798241950 6 3.1416627470548084133 3.1416627470568494473 7 3.1416101765997805905 3.1416101766046906629 8 3.1415970343230776862 3.1415970343215275928 9 3.1415937488171150615 3.1415937487713536668 10 3.1415929278733740748 3.1415929273850979885 11 3.1415927256228504127 3.1415927220386148377 12 3.1415926717412858693 3.1415926707019992125 13 3.1415926189011456060 3.1415926578678454728 14 3.1415926717412858693 3.1415926546593073709 15 3.1415919358822321783 3.1415926538571730119 16 3.1415926717412858693 3.1415926536566394222 17 3.1415810075796233302 3.1415926536065061913 18 3.1415926717412858693 3.1415926535939728836 19 3.1414061547378810956 3.1415926535908393901 20 3.1405434924008406305 3.1415926535900560168 21 3.1400068646912273617 3.1415926535898608396 22 3.1349453756585929919 3.1415926535898122118 23 3.1400068646912273617 3.1415926535897995552 24 3.2245152435345525443 3.1415926535897968907 25 3.1415926535897962246 26 3.1415926535897962246 27 3.1415926535897962246 28 3.1415926535897962246 The true value is 3.14159265358979323846264338327...
While the two forms of the recurrence formula are clearly mathematically equivalent,[nb 14] the first subtracts 1 from a number extremely close to 1, leading to an increasingly problematic loss of significant digits. As the recurrence is applied repeatedly, the accuracy improves at first, but then it deteriorates. It never gets better than about 8 digits, even though 53-bit arithmetic should be capable of about 16 digits of precision. When the second form of the recurrence is used, the value converges to 15 digits of precision.
"Fast math" optimization
The aforementioned lack of associativity of floating-point operations in general means that compilers cannot as effectively reorder arithmetic expressions as they could with integer and fixed-point arithmetic, presenting a roadblock in optimizations such as common subexpression elimination and auto-vectorization.[65] The "fast math" option on many compilers (ICC, GCC, Clang, MSVC...) turns on reassociation along with unsafe assumptions such as a lack of NaN and infinite numbers in IEEE 754. Some compilers also offer more granular options to only turn on reassociation. In either case, the programmer is exposed to many of the precision pitfalls mentioned above for the portion of the program using "fast" math.[66]
In some compilers (GCC and Clang), turning on "fast" math may cause the program to disable subnormal floats at startup, affecting the floating-point behavior of not only the generated code, but also any program using such code as a library.[67]
In most Fortran compilers, as allowed by the ISO/IEC 1539-1:2004 Fortran standard, reassociation is the default, with breakage largely prevented by the "protect parens" setting (also on by default). This setting stops the compiler from reassociating beyond the boundaries of parentheses.[68] Intel Fortran Compiler is a notable outlier.[69]
A common problem in "fast" math is that subexpressions may not be optimized identically from place to place, leading to unexpected differences. One interpretation of the issue is that "fast" math as implemented currently has a poorly defined semantics. One attempt at formalizing "fast" math optimizations is seen in Icing, a verified compiler.[70]
See also
- Arbitrary-precision arithmetic
- C99 for code examples demonstrating access and use of IEEE 754 features.
- Computable number
- Coprocessor
- Decimal floating point
- Double precision
- Experimental mathematics – utilizes high precision floating-point computations
- Fixed-point arithmetic
- Floating-point error mitigation
- FLOPS
- Gal's accurate tables
- GNU MPFR
- Half-precision floating-point format
- IEEE 754 – Standard for Binary Floating-Point Arithmetic
- IBM Floating Point Architecture
- Kahan summation algorithm
- Microsoft Binary Format (MBF)
- Minifloat
- Q (number format) for constant resolution
- Quadruple-precision floating-point format (including double-double)
- Significant figures
- Single-precision floating-point format
Notes
- ^ The significand of a floating-point number is also called mantissa by some authors—not to be confused with the mantissa of a logarithm. Somewhat vague, terms such as coefficient or argument are also used by some. The usage of the term fraction by some authors is potentially misleading as well. The term characteristic (as used e.g. by CDC) is ambiguous, as it was historically also used to specify some form of exponent of floating-point numbers.
- ^ The exponent of a floating-point number is sometimes also referred to as scale. The term characteristic (for biased exponent, exponent bias, or excess n representation) is ambiguous, as it was historically also used to specify the significand of floating-point numbers.
- ^ Hexadecimal (base-16) floating-point arithmetic is used in the IBM System 360 (1964) and 370 (1970) as well as various newer IBM machines, in the RCA Spectra 70 (1964), the Siemens 4004 (1965), 7.700 (1974), 7.800, 7.500 (1977) series mainframes and successors, the Unidata 7.000 series mainframes, the Manchester MU5 (1972), the HEP (1982) computers, and in 360/370-compatible mainframe families made by Fujitsu, Amdahl and Hitachi. It is also used in the Illinois ILLIAC III (1966), Data General Eclipse S/200 (ca. 1974), Gould Powernode 9080 (1980s), Interdata 8/32 (1970s), the SEL Systems 85 and 86 as well as the SDS Sigma 5 (1967), 7 (1966) and Xerox Sigma 9 (1970).
- ^ Octal (base-8) floating-point arithmetic is used in the Ferranti Atlas (1962), Burroughs B5500 (1964), Burroughs B5700 (1971), Burroughs B6700 (1971) and Burroughs B7700 (1972) computers.
- ^ Quaternary (base-4) floating-point arithmetic is used in the Illinois ILLIAC II (1962) computer. It is also used in the Digital Field System DFS IV and V high-resolution site survey systems.
- ^ Base-256 floating-point arithmetic is used in the Rice Institute R1 computer (since 1958).
- ^ Base-65536 floating-point arithmetic is used in the MANIAC II (1956) computer.
- ^ Computer hardware does not necessarily compute the exact value; it simply has to produce the equivalent rounded result as though it had computed the infinitely precise result.
- ^ The enormous complexity of modern division algorithms once led to a famous error. An early version of the Intel Pentium chip was shipped with a division instruction that, on rare occasions, gave slightly incorrect results. Many computers had been shipped before the error was discovered. Until the defective computers were replaced, patched versions of compilers were developed that could avoid the failing cases. See Pentium FDIV bug.
- ^ But an attempted computation of cos(π) yields −1 exactly. Since the derivative is nearly zero near π, the effect of the inaccuracy in the argument is far smaller than the spacing of the floating-point numbers around −1, and the rounded result is exact.
- ^ William Kahan notes: "Except in extremely uncommon situations, extra-precise arithmetic generally attenuates risks due to roundoff at far less cost than the price of a competent error-analyst."
- ^ The Taylor expansion of this function demonstrates that it is well-conditioned near 1: A(x) = 1 − (x−1)/2 + (x−1)^2/12 − (x−1)^4/720 + (x−1)^6/30240 − (x−1)^8/1209600 + ... for |x−1| < π.
- ^ If long double is IEEE quad precision then full double precision is retained; if long double is IEEE double extended precision then additional, but not full precision is retained.
- ^ The equivalence of the two forms can be verified algebraically by noting that the denominator of the fraction in the second form is the conjugate of the numerator of the first. By multiplying the top and bottom of the first expression by this conjugate, one obtains the second expression.
References
- ^ a b c d e f Muller, Jean-Michel; Brisebarre, Nicolas; de Dinechin, Florent; Jeannerod, Claude-Pierre; Lefèvre, Vincent; Melquiond, Guillaume; Revol, Nathalie; Stehlé, Damien; Torres, Serge (2010). Handbook of Floating-Point Arithmetic (1st ed.). Birkhäuser. doi:10.1007/978-0-8176-4705-6. ISBN 978-0-8176-4704-9. LCCN 2009939668.
- ^ a b Sterbenz, Pat H. (1974). Floating-Point Computation. Englewood Cliffs, NJ, United States: Prentice-Hall. ISBN 0-13-322495-3.
- ^ Smith, Steven W. (1997). "Chapter 28, Fixed versus Floating Point". The Scientist and Engineer's Guide to Digital Signal Processing. California Technical Pub. p. 514. ISBN 978-0-9660176-3-2. Retrieved 2012-12-31.
- ^ a b Zehendner, Eberhard (Summer 2008). "Rechnerarithmetik: Fest- und Gleitkommasysteme" (PDF) (Lecture script) (in German). Friedrich-Schiller-Universität Jena. p. 2. Archived (PDF) from the original on 2018-08-07. Retrieved 2018-08-07. [1] (NB. This reference incorrectly gives the MANIAC II's floating point base as 256, whereas it actually is 65536.)
- ^ a b c d Beebe, Nelson H. F. (2017-08-22). "Chapter H. Historical floating-point architectures". The Mathematical-Function Computation Handbook - Programming Using the MathCW Portable Software Library (1st ed.). Salt Lake City, UT, USA: Springer International Publishing AG. p. 948. doi:10.1007/978-3-319-64110-2. ISBN 978-3-319-64109-6. LCCN 2017947446. S2CID 30244721.
- ^ Savard, John J. G. (2018) [2007], "The Decimal Floating-Point Standard", quadibloc, archived from the original on 2018-07-03, retrieved 2018-07-16
- ^ Parkinson, Roger (2000-12-07). "Chapter 2 - High resolution digital site survey systems - Chapter 2.1 - Digital field recording systems". High Resolution Site Surveys (1st ed.). CRC Press. p. 24. ISBN 978-0-20318604-6. Retrieved 2019-08-18.
[…] Systems such as the [Digital Field System] DFS IV and DFS V were quaternary floating-point systems and used gain steps of 12 dB. […]
(256 pages) - ^ Lazarus, Roger B. (1957-01-30) [1956-10-01]. "MANIAC II" (PDF). Los Alamos, NM, USA: Los Alamos Scientific Laboratory of the University of California. p. 14. LA-2083. Archived (PDF) from the original on 2018-08-07. Retrieved 2018-08-07.
[…] the Maniac's floating base, which is 216 = 65,536. […] The Maniac's large base permits a considerable increase in the speed of floating point arithmetic. Although such a large base implies the possibility of as many as 15 lead zeros, the large word size of 48 bits guarantees adequate significance. […]
- ^ Torres Quevedo, Leonardo. Automática: Complemento de la Teoría de las Máquinas, (pdf), pp. 575–583, Revista de Obras Públicas, 19 November 1914.
- ^ Ronald T. Kneusel. Numbers and Computers, Springer, pp. 84–85, 2017. ISBN 978-3319505084
- ^ Randell 1982, pp. 6, 11–13.
- ^ Randell, Brian. Digital Computers, History of Origins, (pdf), p. 545, Digital Computers: Origins, Encyclopedia of Computer Science, January 2003.
- ^ Rojas, Raúl (April–June 1997). "Konrad Zuse's Legacy: The Architecture of the Z1 and Z3" (PDF). IEEE Annals of the History of Computing. 19 (2): 5–16. doi:10.1109/85.586067. Archived (PDF) from the original on 2022-07-03. Retrieved 2022-07-03. (12 pages)
- ^ Rojas, Raúl (2014-06-07). "The Z1: Architecture and Algorithms of Konrad Zuse's First Computer". arXiv:1406.1886 [cs.AR].
- ^ a b Kahan, William Morton (1997-07-15). "The Baleful Effect of Computer Languages and Benchmarks upon Applied Mathematics, Physics and Chemistry. John von Neumann Lecture" (PDF). p. 3. Archived (PDF) from the original on 2008-09-05.
- ^ Randell, Brian, ed. (1982) [1973]. The Origins of Digital Computers: Selected Papers (3rd ed.). Berlin; New York: Springer-Verlag. p. 244. ISBN 978-3-540-11319-5.
- ^ Severance, Charles (1998-02-20). "An Interview with the Old Man of Floating-Point".
- ^ ISO/IEC 9899:1999 - Programming languages - C. Iso.org. §F.2, note 307.
"Extended" is IEC 60559's double-extended data format. Extended refers to both the common 80-bit and quadruple 128-bit IEC 60559 formats.
- ^ "IEEE Floating-Point Representation". 2021-08-03.
- ^ Using the GNU Compiler Collection, i386 and x86-64 Options Archived 2015-01-16 at the Wayback Machine.
- ^ "long double (GCC specific) and __float128". StackOverflow.
- ^ "Procedure Call Standard for the ARM 64-bit Architecture (AArch64)" (PDF). 2013-05-22. Archived (PDF) from the original on 2013-07-31. Retrieved 2019-09-22.
- ^ "ARM Compiler toolchain Compiler Reference, Version 5.03" (PDF). 2013. Section 6.3 Basic data types. Archived (PDF) from the original on 2015-06-27. Retrieved 2019-11-08.
- ^ Kahan, William Morton (2004-11-20). "On the Cost of Floating-Point Computation Without Extra-Precise Arithmetic" (PDF). Archived (PDF) from the original on 2006-05-25. Retrieved 2012-02-19.
- ^ "openEXR". openEXR. Archived from the original on 2013-05-08. Retrieved 2012-04-25.
Since the IEEE-754 floating-point specification does not define a 16-bit format, ILM created the "half" format. Half values have 1 sign bit, 5 exponent bits, and 10 mantissa bits.
- ^ "Technical Introduction to OpenEXR – The half Data Type". openEXR. Retrieved 2024-04-16.
- ^ "IEEE-754 Analysis". Retrieved 2024-08-29.
- ^ a b Borland staff (1998-07-02) [1994-03-10]. "Converting between Microsoft Binary and IEEE formats". Technical Information Database (TI1431C.txt). Embarcadero USA / Inprise (originally: Borland). ID 1400. Archived from the original on 2019-02-20. Retrieved 2016-05-30.
[…] _fmsbintoieee(float *src4, float *dest4) […] MS Binary Format […] byte order => m3 | m2 | m1 | exponent […] m1 is most significant byte => sbbb|bbbb […] m3 is the least significant byte […] m = mantissa byte […] s = sign bit […] b = bit […] MBF is bias 128 and IEEE is bias 127. […] MBF places the decimal point before the assumed bit, while IEEE places the decimal point after the assumed bit. […] ieee_exp = msbin[3] - 2; /* actually, msbin[3]-1-128+127 */ […] _dmsbintoieee(double *src8, double *dest8) […] MS Binary Format […] byte order => m7 | m6 | m5 | m4 | m3 | m2 | m1 | exponent […] m1 is most significant byte => smmm|mmmm […] m7 is the least significant byte […] MBF is bias 128 and IEEE is bias 1023. […] MBF places the decimal point before the assumed bit, while IEEE places the decimal point after the assumed bit. […] ieee_exp = msbin[7] - 128 - 1 + 1023; […]
- ^ a b Steil, Michael (2008-10-20). "Create your own Version of Microsoft BASIC for 6502". pagetable.com. Archived from the original on 2016-05-30. Retrieved 2016-05-30.
- ^ "IEEE vs. Microsoft Binary Format; Rounding Issues (Complete)". Microsoft Support. Microsoft. 2006-11-21. Article ID KB35826, Q35826. Archived from the original on 2020-08-28. Retrieved 2010-02-24.
- ^ a b Kharya, Paresh (2020-05-14). "TensorFloat-32 in the A100 GPU Accelerates AI Training, HPC up to 20x". Retrieved 2020-05-16.
- ^ "NVIDIA Hopper Architecture In-Depth". 2022-03-22.
- ^ 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). "FP8 Formats for Deep Learning". arXiv:2209.05433 [cs.LG].
- ^ Kahan, William Morton (2006-01-11). "How Futile are Mindless Assessments of Roundoff in Floating-Point Computation?" (PDF). Archived (PDF) from the original on 2004-12-21.
- ^ a b Gay, David M. (1990). Correctly Rounded Binary-Decimal and Decimal-Binary Conversions (Technical report). NUMERICAL ANALYSIS MANUSCRIPT 90-10, AT&T BELL LABORATORIES. CiteSeerX 10.1.1.31.4049. (dtoa.c in netlab)
- ^ Loitsch, Florian (2010). "Printing floating-point numbers quickly and accurately with integers" (PDF). Proceedings of the 31st ACM SIGPLAN Conference on Programming Language Design and Implementation. PLDI '10: ACM SIGPLAN Conference on Programming Language Design and Implementation. pp. 233–243. doi:10.1145/1806596.1806623. ISBN 978-1-45030019-3. S2CID 910409. Archived (PDF) from the original on 2014-07-29.
- ^ "Added Grisu3 algorithm support for double.ToString(). by mazong1123 · Pull Request #14646 · dotnet/coreclr". GitHub.
- ^ Adams, Ulf (2018-12-02). "Ryū: fast float-to-string conversion". ACM SIGPLAN Notices. 53 (4): 270–282. doi:10.1145/3296979.3192369. S2CID 218472153.
- ^ Giulietti, Rafaello. "The Schubfach way to render doubles".
- ^ "abolz/Drachennest". GitHub. 2022-11-10.
- ^ "google/double-conversion". GitHub. 2020-09-21.
- ^ Lemire, Daniel (2021-03-22). "Number parsing at a gigabyte per second". Software: Practice and Experience. 51 (8): 1700–1727. arXiv:2101.11408. doi:10.1002/spe.2984. S2CID 231718830.
- ^ a b c Goldberg, David (March 1991). "What Every Computer Scientist Should Know About Floating-Point Arithmetic". ACM Computing Surveys. 23 (1): 5–48. doi:10.1145/103162.103163. S2CID 222008826. (With the addendum "Differences Among IEEE 754 Implementations": [2], [3])
- ^ Patterson, David A.; Hennessy, John L. (2014). Computer Organization and Design, The Hardware/Software Interface. The Morgan Kaufmann series in computer architecture and design (5th ed.). Waltham, Massachusetts, USA: Elsevier. p. 793. ISBN 978-9-86605267-5.
- ^ a b US patent 3037701A, Huberto M Sierra, "Floating decimal point arithmetic control means for calculator", issued 1962-06-05
- ^ a b Kahan, William Morton (1997-10-01). "Lecture Notes on the Status of IEEE Standard 754 for Binary Floating-Point Arithmetic" (PDF). p. 9. Archived (PDF) from the original on 2002-06-22.
- ^ "D.3.2.1". Intel 64 and IA-32 Architectures Software Developers' Manuals. Vol. 1.
- ^ Harris, Richard (October 2010). "You're Going To Have To Think!". Overload (99): 5–10. ISSN 1354-3172. Retrieved 2011-09-24.
Far more worrying is cancellation error which can yield catastrophic loss of precision.
[4] - ^ Christopher Barker: PEP 485 -- A Function for testing approximate equality
- ^ "Patriot missile defense, Software problem led to system failure at Dharhan, Saudi Arabia". US Government Accounting Office. GAO report IMTEC 92-26.
- ^ Wilkinson, James Hardy (2003-09-08). "Error Analysis". In Ralston, Anthony; Reilly, Edwin D.; Hemmendinger, David (eds.). Encyclopedia of Computer Science. Wiley. pp. 669–674. ISBN 978-0-470-86412-8. Retrieved 2013-05-14.
- ^ Einarsson, Bo (2005). Accuracy and reliability in scientific computing. Society for Industrial and Applied Mathematics (SIAM). pp. 50–. ISBN 978-0-89871-815-7. Retrieved 2013-05-14.
- ^ a b c d Higham, Nicholas John (2002). Accuracy and Stability of Numerical Algorithms (2nd ed.). Society for Industrial and Applied Mathematics (SIAM). pp. 27–28, 110–123, 493. ISBN 978-0-89871-521-7. 0-89871-355-2.
- ^ 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.
- ^ a b Kahan, William Morton (2005-07-15). Floating-Point Arithmetic Besieged by "Business Decisions" (PDF). IEEE-sponsored ARITH 17, Symposium on Computer Arithmetic (Keynote Address). pp. 6, 18. Archived (PDF) from the original on 2006-03-17. Retrieved 2013-05-23. (NB. Kahan estimates that the incidence of excessively inaccurate results near singularities is reduced by a factor of approx. 1/2000 using the 11 extra bits of precision of double extended.)
- ^ Kahan, William Morton (2011-08-03). Desperately Needed Remedies for the Undebuggability of Large Floating-Point Computations in Science and Engineering (PDF). IFIP/SIAM/NIST Working Conference on Uncertainty Quantification in Scientific Computing, Boulder, CO. p. 33. Archived (PDF) from the original on 2013-06-20.
- ^ Kahan, William Morton; Darcy, Joseph (2001) [1998-03-01]. "How Java's floating-point hurts everyone everywhere" (PDF). Archived (PDF) from the original on 2000-08-16. Retrieved 2003-09-05.
- ^ a b c d Kahan, William Morton (2000-08-27). "Marketing versus Mathematics" (PDF). pp. 15, 35, 47. Archived (PDF) from the original on 2003-08-15.
- ^ Kahan, William Morton (1981-02-12). "Why do we need a floating-point arithmetic standard?" (PDF). p. 26. Archived (PDF) from the original on 2004-12-04.
- ^ Kahan, William Morton (2001-06-04). Bindel, David (ed.). "Lecture notes of System Support for Scientific Computation" (PDF). Archived (PDF) from the original on 2013-05-17.
- ^ "General Decimal Arithmetic". Speleotrove.com. Retrieved 2012-04-25.
- ^ Christiansen, Tom; Torkington, Nathan; et al. (2006). "perlfaq4 / Why is int() broken?". perldoc.perl.org. Retrieved 2011-01-11.
- ^ Shewchuk, Jonathan Richard (1997). "Adaptive Precision Floating-Point Arithmetic and Fast Robust Geometric Predicates". Discrete & Computational Geometry. 18 (3): 305–363. doi:10.1007/PL00009321.
- ^ Kahan, William Morton; Ivory, Melody Y. (1997-07-03). "Roundoff Degrades an Idealized Cantilever" (PDF). Archived (PDF) from the original on 2003-12-05.
- ^ "Auto-Vectorization in LLVM". LLVM 13 documentation.
We support floating point reduction operations when -ffast-math is used.
- ^ "FloatingPointMath". GCC Wiki.
- ^ "55522 – -funsafe-math-optimizations is unexpectedly harmful, especially w/ -shared". gcc.gnu.org.
- ^ "Code Gen Options (The GNU Fortran Compiler)". gcc.gnu.org.
- ^ "Bug in zheevd · Issue #43 · Reference-LAPACK/lapack". GitHub.
- ^ Becker, Heiko; Darulova, Eva; Myreen, Magnus O.; Tatlock, Zachary (2019). Icing: Supporting Fast-Math Style Optimizations in a Verified Compiler. CAV 2019: Computer Aided Verification. Vol. 11562. pp. 155–173. doi:10.1007/978-3-030-25543-5_10.
Further reading
- Wilkinson, James Hardy (1963). Rounding Errors in Algebraic Processes (1st ed.). Englewood Cliffs, New Jersey, USA: Prentice-Hall, Inc. ISBN 9780486679990. MR 0161456. (NB. Classic influential treatises on floating-point arithmetic.)
- Wilkinson, James Hardy (1965). The Algebraic Eigenvalue Problem. Monographs on Numerical Analysis (1st ed.). Oxford University Press / Clarendon Press. ISBN 9780198534037. Retrieved 2016-02-11.
- Sterbenz, Pat H. (1974). Floating-Point Computation. Prentice-Hall Series in Automatic Computation (1st ed.). Englewood Cliffs, New Jersey, USA: Prentice Hall. ISBN 978-0-13-322495-5.
- Golub, Gene F.; van Loan, Charles F. (1986). Matrix Computations (3rd ed.). Johns Hopkins University Press. ISBN 978-0-8018-5413-2.
- Press, William Henry; Teukolsky, Saul A.; Vetterling, William T.; Flannery, Brian P. (2007) [1986]. Numerical Recipes - The Art of Scientific Computing (3rd ed.). Cambridge University Press. ISBN 978-0-521-88407-5. (NB. Edition with source code CD-ROM.)
- Knuth, Donald Ervin (1997). "Section 4.2: Floating-Point Arithmetic". The Art of Computer Programming, Vol. 2: Seminumerical Algorithms (3rd ed.). Addison-Wesley. pp. 214–264. ISBN 978-0-201-89684-8.
- Blaauw, Gerrit Anne; Brooks, Jr., Frederick Phillips (1997). Computer Architecture: Concepts and Evolution (1st ed.). Addison-Wesley. ISBN 0-201-10557-8. (1213 pages) (NB. This is a single-volume edition. This work was also available in a two-volume version.)
- Savard, John J. G. (2018) [2005], "Floating-Point Formats", quadibloc, archived from the original on 2018-07-03, retrieved 2018-07-16
- Muller, Jean-Michel; Brunie, Nicolas; de Dinechin, Florent; Jeannerod, Claude-Pierre; Joldes, Mioara; Lefèvre, Vincent; Melquiond, Guillaume; Revol, Nathalie; Torres, Serge (2018) [2010]. Handbook of Floating-Point Arithmetic (2nd ed.). Birkhäuser. doi:10.1007/978-3-319-76526-6. ISBN 978-3-319-76525-9. LCCN 2018935254.
External links
- "Survey of Floating-Point Formats". (NB. This page gives a very brief summary of floating-point formats that have been used over the years.)
- Monniaux, David (May 2008). "The pitfalls of verifying floating-point computations". 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. (NB. A compendium of non-intuitive behaviors of floating point on popular architectures, with implications for program verification and testing.)
- OpenCores. (NB. This website contains open source floating-point IP cores for the implementation of floating-point operators in FPGA or ASIC devices. The project double_fpu contains verilog source code of a double-precision floating-point unit. The project fpuvhdl contains vhdl source code of a single-precision floating-point unit.)
- Fleegal, Eric (2004). "Microsoft Visual C++ Floating-Point Optimization". Microsoft Developer Network. Archived from the original on 2017-07-06.