Soy consciente de que la aritmética de coma flotante tiene problemas de precisión. Por lo general, los supero cambiando a una representación decimal fija del número, o simplemente descuidando el error.
Sin embargo, no sé cuáles son las causas de esta inexactitud. ¿Por qué hay tantos problemas de redondeo con números flotantes?
decimal
tipo de .NET . El punto fijo, por otro lado, es diferente. Mientras su rango sea limitado, el punto fijo es una buena respuesta. Pero el rango restrictivo hace que el punto fijo no sea adecuado para muchas aplicaciones matemáticas, y como resultado las implementaciones de números de punto fijo a menudo no están bien optimizadas en hardware.Respuestas:
Esto se debe a que algunas fracciones necesitan una cantidad muy grande (o incluso infinita) de lugares para expresarse sin redondear. Esto es válido tanto para la notación decimal como para el binario o cualquier otro. Si limitara la cantidad de lugares decimales para usar en sus cálculos (y evitar hacer cálculos en notación de fracciones), tendría que redondear incluso una expresión simple como 1/3 + 1/3. En lugar de escribir 2/3 como resultado, tendría que escribir 0.33333 + 0.33333 = 0.66666 que no es idéntico a 2/3.
En el caso de una computadora, el número de dígitos está limitado por la naturaleza técnica de sus registros de memoria y CPU. La notación binaria utilizada internamente agrega algunas dificultades más. Las computadoras normalmente no pueden expresar números en notación de fracciones, aunque algunos lenguajes de programación agregan esta capacidad, lo que permite evitar esos problemas hasta cierto punto.
Lo que todo informático debe saber sobre la aritmética de coma flotante
fuente
Principalmente, los errores de redondeo provienen del hecho de que el infinito de todos los números reales no puede ser representado por la memoria finita de una computadora , y mucho menos una pequeña porción de memoria, como una variable de punto flotante , por lo que muchos números almacenados son solo aproximaciones de El número que deben representar.
Como solo hay un número limitado de valores que no son una aproximación, y cualquier operación entre una aproximación y otro número da como resultado una aproximación, los errores de redondeo son casi inevitables .
Lo importante es darse cuenta de cuándo es probable que causen un problema y tomar medidas para mitigar los riesgos .
Además de lo esencial de David Goldberg Lo que todo informático debe saber sobre la aritmética de punto flotante (reeditado por Sun / Oracle como un apéndice de su Guía de cálculo numérico ), que fue mencionado por thorsten , la revista ACCU Overload tuvo un excelente serie de artículos de Richard Harris sobre el Floating Point Blues .
La serie comenzó con
Richard comienza explicando la taxonomía de los números reales, racionales, irracionales, algebraicos y trascendentales. Luego continúa explicando la representación IEEE754, antes de pasar a un error de cancelación y problemas de orden de ejecución.
Si no lees más profundo que esto, tendrás una excelente base en los problemas asociados con los números de coma flotante.
Sin embargo, si quieres saber más, él continúa con
Luego cambia a tratar de ayudarlo a curar sus Azules de cálculo
y por último pero no menos importante, hay
Vale la pena examinar toda la serie de artículos, y con 66 páginas en total, aún son más pequeñas que las 77 páginas del artículo de Goldberg .
Si bien esta serie cubre gran parte del mismo terreno, la encontré bastante más accesible que el artículo de Goldberg . También me resultó más fácil entender las partes más complejas del documento después de leer los artículos anteriores de Richards y después de esos primeros artículos, Richard se ramifica en muchas áreas interesantes que el documento de Goldberg no menciona.
Como así se dijo en los comentarios:
fuente
Bueno, thorsten tiene el vínculo definitivo . Yo podria agregar:
Cualquier forma de representación tendrá algún error de redondeo para algún número. Intente expresar 1/3 en coma flotante IEEE o en decimal. Ninguno de los dos puede hacerlo con precisión. Esto va más allá de responder su pregunta, pero he usado esta regla general con éxito:
fuente
Lo que parece no haberse mencionado hasta ahora son los conceptos de un algoritmo inestable y un problema mal condicionado . Primero abordaré el primero, ya que parece ser un obstáculo más frecuente para los expertos en numeración novatos.
Considere el cálculo de los poderes de la proporción áurea (recíproca)
φ=0.61803…
; Una forma posible de hacerlo es usar la fórmula de recursiónφ^n=φ^(n-2)-φ^(n-1)
, comenzando conφ^0=1
yφ^1=φ
. Si ejecuta esta recursividad en su entorno informático favorito y compara los resultados con potencias evaluadas con precisión, encontrará una erosión lenta de cifras significativas. Esto es lo que sucede, por ejemplo, en Mathematica :El resultado pretendido para
φ^41
tiene el signo incorrecto, e incluso antes, los valores calculados y reales paraφ^39
compartir sin dígitos en común (3.484899258054952
* ^ - 9for the computed version against the true value
7.071019424062048*^-9
). El algoritmo es, por lo tanto, inestable, y uno no debe usar esta fórmula de recursión en aritmética inexacta. Esto se debe a la naturaleza inherente de la fórmula de recursión: hay una solución "en descomposición" y "creciente" para esta recursión, y tratar de calcular la solución "en descomposición" mediante una solución directa cuando hay una solución alternativa "creciente" está rogando por pena numérica. Por lo tanto, uno debe asegurarse de que sus algoritmos numéricos sean estables.Ahora, con el concepto de un problema mal condicionado : aunque puede haber una forma estable de hacer algo numéricamente, es muy posible que el problema que tiene no pueda ser resuelto por su algoritmo. Esto es culpa del problema en sí, y no del método de solución. El ejemplo canónico en numéricos es la solución de ecuaciones lineales que involucran la llamada "matriz de Hilbert":
La matriz es el ejemplo canónico de una matriz mal acondicionada : tratar de resolver un sistema con una gran matriz de Hilbert podría devolver una solución inexacta.
Aquí hay una demostración de Mathematica : compare los resultados de la aritmética exacta
y aritmética inexacta
(Si lo probó en Mathematica , notará algunos mensajes de error que advierten sobre la aparición de problemas).
En ambos casos, simplemente aumentar la precisión no es una cura; solo retrasará la inevitable erosión de las figuras.
Esto es a lo que te puedes enfrentar. Las soluciones pueden ser difíciles: para el primero, puede volver al tablero de dibujo o leer revistas / libros / lo que sea para encontrar si alguien más ha encontrado una solución mejor que usted; para el segundo, te rindes o reformulas tu problema a algo más manejable.
Te dejo con una cita de Dianne O'Leary:
fuente
porque los números decimales de base 10 no se pueden expresar en base 2
o en otras palabras, 1/10 no se puede transformar en una fracción con una potencia de 2 en el denominador (que es lo que son esencialmente los números de coma flotante)
fuente
9*3.3333333
en decimal y compárelo con9*3 1/3
.1 + .1 != .2
porque se usa codificación binaria de punto flotante, no decimal.1.0/3.0*3.0 != 1.0
, como se usa la codificación binaria de punto flotante, no trinaria.En matemáticas, hay infinitos números racionales. Una variable de 32 bits solo puede tener 2 32 valores diferentes, y una variable de 64 bits solo 2 valores de 64 . Por lo tanto, hay infinitos números racionales que no tienen una representación precisa.
Podríamos idear esquemas que nos permitieran representar 1/3 perfectamente, o 1/100. Resulta que para muchos propósitos prácticos esto no es muy útil. Hay una gran excepción: en las finanzas, las fracciones decimales a menudo aparecen. Esto se debe principalmente a que las finanzas son esencialmente una actividad humana, no física.
Por lo tanto, generalmente elegimos usar punto flotante binario y redondear cualquier valor que no pueda representarse en binario. Pero en finanzas, a veces elegimos coma flotante decimal y redondeamos los valores al valor decimal más cercano.
fuente
"√2"
. (Mi vieja calculadora HP-48 fue capaz de hacer exactamente eso, y la cuadratura de ese valor resultó exactamente2.0
). Solo hay un infinito contable de números reales representables para cualquier representación finita, pero ningún cálculo puede arrojar un número que no lo sea, en principio, representable. En la práctica, el punto flotante binario limita drásticamente el conjunto de números representables, con el beneficio de una velocidad increíble y un pequeño almacenamiento en relación con las representaciones simbólicas.El único "problema de redondeo" realmente obvio con los números de punto flotante que pienso es con los filtros de promedio móvil:
$$ \ begin {align} y [n] & = \ frac {1} {N} \ sum \ limits_ {i = 0} ^ {N-1} x [ni] \ & = y [n-1] + \ frac {1} {N} (x [n] - x [nN]) \ \ end {align} $$
para que esto funcione sin la acumulación de ruido, debe asegurarse de que los $ x [n] $ que agregue en las muestras actuales sean exactamente iguales a los $ x [nN] $ que restará $ N $ muestras en futuro. si no es así, lo que es diferente es un pequeño turd que se atasca en su línea de retraso y nunca saldrá. eso se debe a que este filtro de promedio móvil está construido con un IIR que tiene un polo marginalmente estable en $ z = 1 $ y un cero que lo cancela por dentro. pero es un integrador y cualquier basura que se integre y no se elimine por completo existirá en la suma del integrador para siempre. Aquí es donde el punto fijo no tiene el mismo problema que los números de punto flotante.
fuente