Lo que todo programador debería saber sobre aritmética de punto flotante
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

Traducidos capítulos sobre comparación y propagación de errores

+84 -63
+64 -39
content/errors/comparison.html
··· 1 1 --- 2 - title: Comparison 3 - description: Explanation of the various pitfalls in comparing floating-point numbers. 2 + title: Comparación 3 + description: Explicación de los diversos problemas al comparar números de punto flotante 4 4 --- 5 5 6 - Due to rounding errors, most [floating-point](/formats/fp/) numbers end up being slightly imprecise. As long as this 7 - imprecision stays small, it can usually be ignored. However, it also means that numbers expected 8 - to be equal (e.g. when calculating the same result through different correct methods) often differ 9 - slightly, and a simple equality test fails. For example: 6 + Debido a los errores de redondeo, la mayoría de los números de [punto flotante](/formats/fp/) 7 + terminan siendo ligeramente imprecisos. Mientras esta imprecisión se mantenga pequeña, 8 + normalmente se puede ignorar. Sin embargo, esto significa también que números que se 9 + espera que sean iguales (por ejemplo al calcular el mismo resultado utilizando distintos 10 + métodos correctos) a veces difieren levemente, y una simple prueba de igualdad falla. 11 + Por ejemplo: 10 12 11 13 float a = 0.15 + 0.15 12 14 float b = 0.1 + 0.2 13 - if(a == b) // can be false! 14 - if(a >= b) // can also be false! 15 + if(a == b) // ¡Puede ser falso! 16 + if(a >= b) // ¡También puede ser falso! 15 17 16 - Don't use absolute error margins 17 - -------------------------------- 18 - The solution is to check not whether the numbers are exactly the same, but whether their difference is 19 - very small. The error margin that the difference is compared to is often called *epsilon*. 20 - The most simple form: 18 + No usar márgenes de error absolutos 19 + ----------------------------------- 21 20 22 - if( Math.abs(a-b) < 0.00001) // wrong - don't do this 21 + La solución es comprobar no si los números son exactamente iguales, sino si su 22 + diferencia es muy pequeña. El margen de error frente al que se compara esta diferencia 23 + normalmente se llama *epsilon*. En su forma más simple: 23 24 24 - This is a bad way to do it because a fixed epsilon chosen because it "looks small" could actually be way too 25 - large when the numbers being compared are very small as well. The comparison would return "true" for numbers that are quite different. And when the numbers are very large, the epsilon 26 - could end up being smaller than the smallest rounding error, so that the comparison always returns "false". 27 - Therefore, it is necessary to see whether the *relative error* is smaller than epsilon: 25 + if(Math.abs(a-b) < 0.00001) // Mal - no hacer esto 28 26 29 - if( Math.abs((a-b)/b) < 0.00001 ) // still not right! 27 + Esto es una mala forma de hacerlo porque un epsilon fijo elegido porque «parece 28 + pequeño» podría perfectamente ser demasiado grande cuando los números que se 29 + comparan son también muy pequeños. La comparación devolvería «verdadero» para 30 + números muy diferentes. Y cuando los números son muy grandes, el epsilon 31 + puede acabar siendo más pequeño que el mínimo error de redondeo, por lo que 32 + la comparación siempre devolvería «falso». Por tanto, es necesario ver si 33 + el *error relativo* es menor epsilon: 30 34 31 - Look out for edge cases 35 + if(Math.abs((a-b)/b) < 0.00001) // ¡Todavía no es correcto! 36 + 37 + Vigila los casos límite 32 38 ----------------------- 33 - There are some important special cases where this will fail: 39 + 40 + Hay algunos casos especiales importantes para los que esto falla: 34 41 35 - * When both `a` and `b` are zero. `0.0/0.0` is "not a number", which causes an exception on some platforms, or returns false for all comparisons. 36 - * When only `b` is zero, the division yields "infinity", which may also cause an exception, or is greater than epsilon even when `a` is smaller. 37 - * It returns `false` when both `a` and `b` are very small but on opposite sides of zero, even when they're the smallest possible non-zero numbers. 42 + * Cuando tanto `a` como `b` son cero. `0.0/0.0` es NaN, lo que provoca una excepción en algunas plataformas o devuelve falso para todas las comparaciones. 43 + * Cuando solo `b` es cero, la división devuelve infinito, lo que también puede causar una excepción, o es mayor que epsilon incluso cuando `a` es más pequeño. 44 + * Devuelve «falso» cuando tanto `a` como `b` son muy pequeños pero a ambos lados del cero, incluso cuando son los números no nulos más pequeños. 38 45 39 - Also, the result is not commutative (`nearlyEquals(a,b)` is not always the same as `nearlyEquals(b,a)`). To fix these problems, the code has to get a lot more complex, so we really need to put it into a function of its own: 46 + Además, el resultado no es conmutativo (`nearlyEquals(a,b)` no es siempre lo mismo que 47 + `nearlyEquals(b,a)`). Para solucionar estos problemas, el código tiene que ser mucho más 48 + complejo, así que necesitamos meterlo en una función: 40 49 41 50 public static boolean nearlyEqual(float a, float b, float epsilon) 42 51 { ··· 44 53 final float absB = Math.abs(b); 45 54 final float diff = Math.abs(a - b); 46 55 47 - if (a == b) { // shortcut, handles infinities 56 + if (a == b) { // Atajo, maneja los infinitos 48 57 return true; 49 - } else if (a * b == 0) { // a or b or both are zero 50 - // relative error is not meaningful here 58 + } else if (a * b == 0) { // a o b o ambos son cero 59 + // El error relativo no es importante aquí 51 60 return diff < (epsilon * epsilon); 52 - } else { // use relative error 61 + } else { // Usar el error relativo 53 62 return diff / (absA + absB) < epsilon; 54 63 } 55 64 } 56 65 57 - This method [passes tests](../NearlyEqualsTest.java) for many important special cases, but as you can see, it 58 - uses some quite non-obvious logic. In particular, it has to use a completely different definition of error margin 59 - when `a` or `b` is zero, because the classical definition of relative error becomes meaningless in those cases. 66 + Este método [pasa las pruebas](../NearlyEqualsTest.java) para muchos casos especiales 67 + importantes, pero como puedes ver, utiliza cierta lógica no trivial. En particular, 68 + tiene que utilizar una definición totalmente distinta del margen de error cuando 69 + `a` o `b` son cero, porque la definición clásica del error relativo es inútil en 70 + esos casos. 71 + 72 + Hay algunos casos en los que el método de arriba todavía produce resultados inesperados 73 + (concretamente, es mucho más estricto cuando un valor es casi cero que cuando es 74 + exactamente cero), y algunas de esas pruebas para las que fue desarrollado probablemente 75 + especifica un comportamiento que no es apropiado para algunas aplicaciones. ¡Antes de 76 + usarlo, asegúrate de que es adecuado para tu aplicación! 60 77 61 - There are some cases where the method above still produces unexpected results (in particular, it's much stricter when one value is nearly zero than when it is exactly zero), and some of the tests 62 - it was developed to pass probably specify behaviour that is not appropriate for some applications. Before using it, make sure it's appropriate for your application! 78 + Comparando valores de punto flotante como enteros 79 + ------------------------------------------------- 63 80 64 - Comparing floating-point values as integers 65 - ------------------------------------------- 66 - There is an alternative to heaping conceptual complexity onto such an apparently simple task: instead of comparing `a` and `b` as [real numbers](http://en.wikipedia.org/wiki/Real_numbers), we can think about them as discrete steps and define the error margin as the maximum number of possible floating-point values between the two values. 81 + Hay una alternativa a aplicar toda esta complejidad conceptual a una tarea aparentemente 82 + tan sencilla: en lugar de comparar `a` y `b` como [números 83 + reales](http://es.wikipedia.org/wiki/N%C3%BAmero_real), podemos concebirlos como pasos 84 + discretos y definir el margen de error como el número máximo de valores de punto flotante 85 + posibles entre esos dos números. 67 86 68 - This is conceptually very clear and easy and has the advantage of implicitly scaling the relative error margin with the magnitude of the values. Technically, it's a bit more complex, but not as much as you might think, because IEEE 754 floats are designed to maintain their order when their bit patterns are interpreted as integers. 87 + Esto es conceptualmente muy evidente y fácil y tiene la ventaja de que escala 88 + implícitamente el margen de error relativo con la magnitud de los valores. 89 + Técnicamente es un poco más complejo, pero no mucho más de lo que puedas pensar, 90 + porque los números del IEEE 754 están diseñados para mantener su orden cuando 91 + sus secuencias de bits se interpretan como enteros. 69 92 70 - However, this method does require the programming language to support conversion between floating-point values and integer bit patterns. Read the [Comparing floating-point numbers](/references/) paper for more details. 93 + Sin embargo, este método requiere que el lenguaje de programación soporte conversión 94 + entre valores de punto flotante y secuencias de bits enteras. Lee el artículo en 95 + inglés [Comparing floating-point numbers](/references/) para más detalles.
+18 -22
content/errors/propagation.html
··· 1 1 --- 2 - title: Error Propagation 3 - description: Explanations about propagation of errors in floating-point math. 2 + title: Propagación del error 3 + description: Explicaciones sobre la propagación de errores en aritmética de punto flotante 4 4 --- 5 5 6 - While the errors in single [floating-point numbers](/formats/fp/) are very small, even simple calculations on them 7 - can contain pitfalls that increase the error in the result way beyond just having the individual 8 - errors "add up". 6 + Aunque los errores en [números de punto flotante](/formats/fp/) aislados son muy pequeños, 7 + operaciones simples con ellos pueden tener problemas e incrementar el error del resultado 8 + más de lo que se esperaría «sumando» los errores individuales. 9 9 10 - In general: 10 + En general: 11 11 12 - * Multiplication and division are "safe" operations 13 - * Addition and subtraction are dangerous, because when numbers of different magnitudes are involved, 14 - digits of the smaller-magnitude number are lost. 15 - * This loss of digits can be inevitable and benign (when the lost digits also insignificant for 16 - the final result) or catastrophic (when the loss is magnified and distorts the result strongly). 17 - * The more calculations are done (especially when they form an iterative algorithm) the more important 18 - it is to consider this kind of problem. 19 - * A method of calculation can be *stable* (meaning that it tends to reduce rounding errors) 20 - or *unstable* (meaning that rounding errors are magnified). Very often, there are both stable 21 - and unstable solutions for a problem. 12 + * La multiplicación y la división son operaciones «seguras». 13 + * La suma y la resta son peligrosas, porque cuando hay involucrados números de diferentes órdenes de magnitud, los dígitos del más pequeño se pierden. 14 + * Esta pérdida de dígitos puede ser inevitable y benigna (cuando los dígitos perdidos son también insignificantes para el resultado final) o catastrófica (cuando la pérdida se amplifica y distorsiona el resultado fuertemente). 15 + * Cuantas más operaciones se hagan (especialmente cuando forman parte de un algoritmo iterativo) más importante es considerar este problema. 16 + * Un método de cálculo puede ser *estable* (tiende a reducir los errores de redondeo) o *inestable* (los errores de redondeo se amplifican). A menudo, hay soluciones estables e inestables a un problema. 22 17 23 - There is an entire sub-field of mathematics (in [numerical analysis](http://en.wikipedia.org/wiki/Numerical_analysis)) devoted to studying the numerical stability 24 - of algorithms. For doing complex calculations involving floating-point numbers, it is absolutely 25 - necessary to have some understanding of this discipline. 18 + Hay un área entera de las matemáticas (el [análisis 19 + numérico](http://es.wikipedia.org/wiki/An%C3%A1lisis_num%C3%A9rico)) dedicada a estudiar la 20 + estabilidad numérica de los algoritmos. Para hacer cálculos complejos utilizando números de punto 21 + flotante, es absolutamente necesario tener ciertos conocimientos en esta materia. 26 22 27 - The article [What Every Computer Scientist Should Know About Floating-Point Arithmetic](/references/) gives a detailed introduction, 28 - and served as an inspiration for creating this website, mainly due to being a bit too detailed and 29 - intimidating to programmers without a scientific background. 23 + Este artículo en inglés [What Every Computer Scientist Should Know About Floating-Point Arithmetic](/references/) 24 + da una introducción detallada, y sirvió de inspiración para esta web, principalmente por el hecho 25 + de que era demasiado minucioso y un poco intimidante para programadores sin una formación científica.
+2 -2
content/style.css
··· 2 2 font-family: Helvetica, Arial, sans-serif; 3 3 } 4 4 5 - pre, code, tt{ 6 - font-family: Courier, serif; 5 + pre, code, tt { 6 + font-family: Courier, monospace; 7 7 } 8 8 9 9 body {