Hay dos conceptos separados que a menudo se combinan: precisión y precisión .
Por ejemplo, si te dijera que [matemáticas] \ pi = 3 [/ matemáticas], esa afirmación es muy precisa , pero solo con una precisión de 1 dígito. Ningún otro valor de un solo dígito está más cerca de [math] \ pi [/ math].
Si en cambio dije [matemáticas] \ pi = 3.0000000 [/ matemáticas], mi declaración es más precisa (8 dígitos), pero menos precisa en relación con su precisión.
- ¿Es posible tener una máquina de Turing que sea capaz de construir otra máquina de Turing (diferente) a partir de bits puramente aleatorios?
- ¿Por qué es más fácil la adición de peano para una computadora?
- ¿Travel seles man proplem es np o np completo o np difícil?
- ¿Qué es una variable?
- Cómo usar algoritmos y estructura de datos en la vida real
La precisión indica qué tan cerca está el valor que tiene (ya sea calculado o medido) del valor “verdadero”.
La precisión indica la resolución de su valor, es decir, qué tan separados deben estar dos valores antes de poder distinguirlos.
Este diagrama ilustra:
(Fuente: “Precisión vs. Precisión … ¿Conoces la diferencia?” )
Editar: Fred Goldrich señala que pasé por alto un punto aquí, así que déjame expandirme un poco. Cuando dije que [math] \ pi = 3.0000000 [/ math] es menos preciso en relación con su precisión en comparación con [math] \ pi = 3 [/ math], no ofrecí ninguna motivación para la frase relativa a su precisión.
Cuando declaras que un número tiene un cierto número de dígitos significativos de precisión, lo que realmente estás diciendo es que el número representa el centro de un intervalo de valores. El tamaño de este intervalo está determinado por las unidades en último lugar.
Por ejemplo, cuando digo [matemáticas] \ pi = 3 [/ matemáticas] a 1 dígito significativo de precisión, el número [matemáticas] 3 [/ matemáticas] aquí realmente representa el intervalo [matemáticas] (2.5,3.5) [ /matemáticas]. Este intervalo incluye el valor real de [math] \ pi [/ math]. Este número de baja precisión corresponde a la diana en la esquina inferior izquierda del diagrama de arriba. Todas las marcas están agrupadas alrededor del centro, pero todavía hay una distribución bastante amplia entre las marcas en los extremos del rango.
Cuando digo [matemática] \ pi = 3.0000000 [/ matemática] a 8 dígitos significativos de precisión, el número [matemática] 3.0000000 [/ matemática] representa el intervalo [matemática] [2.99999995,3.00000005] [/ matemática]. Ese es un intervalo mucho más pequeño. También está lejos del verdadero valor, en términos de las unidades en último lugar . Esto corresponde a la situación en la diana superior derecha, donde todas las marcas están muy juntas, pero todo el grupo está lejos del objetivo.
Ahora, cuanto más astuto note, escribí uno de esos intervalos como un intervalo abierto, y uno como un intervalo cerrado. Eso es para mantenerlo consistente con el modo de redondeo predeterminado de IEEE 754 de redondeo a par .
La mayoría de las computadoras actualmente implementan la aritmética de coma flotante binaria IEEE 754. IEEE 754 especifica reglas muy cuidadosas para garantizar resultados precisos con la precisión disponible. También especifica diferentes grados de precisión para diferentes aplicaciones. Por ejemplo, hay precisión simple de 32 bits, precisión extendida de 43 bits y precisión doble de 64 bits.
Las reglas de redondeo en IEEE 754 son muy estrictas, lo que permite que un programador cuidadoso produzca resultados correctamente redondeados. El Dr. William Kahan, la mayor fuerza detrás de IEEE 754–1985, ha publicado varios artículos y presentaciones sobre cómo escribir algoritmos correctamente redondeados. Escritos correctamente, los algoritmos matemáticos serán precisos dentro de la precisión requerida.
Este es un punto importante: muchas personas tratan el punto flotante como “intrínsecamente borroso e inexacto”. No lo es. Existen reglas muy estrictas sobre cómo se realizan los cálculos de coma flotante, que incluyen:
- Circunstancias bajo las cuales se requieren cálculos para ser exactos.
- El comportamiento de redondeo preciso esperado cuando los cálculos son inexactos.
No es una “aritmética difusa” como la que podrías obtener de alguien que estima números en el reverso de una servilleta, o que podrías obtener cuando usas una regla de cálculo. Es 100% predecible y está diseñado para que sea posible escribir un buen software.
Nota : ¡ Eso no impide que la gente escriba mal software! Sin embargo, la aritmética subyacente no es el culpable allí.
Nota 2 : Sergey Zubkov señaló en otra respuesta que C y C ++ hacen que sea más difícil de lo que te gustaría escribir un buen software numérico en esos idiomas. Sin embargo, el hardware subyacente tiene reglas estrictas.
También te sorprenderá la poca precisión que realmente necesitas para obtener resultados bastante buenos. Por ejemplo, Marte está [matemáticas] 227.9 \ veces 10 ^ {9} \ mbox {m} [/ matemáticas] del sol. Un número de coma flotante de precisión simple tiene una precisión de 1 parte en [matemática] 2 ^ {24} = 16777216 [/ matemática]. Entonces, en el radio completo de la órbita de Marte, un flotador de precisión simple tiene una precisión de aproximadamente 13,6 km. Puede parecer mucho, pero en comparación con el tamaño de Marte y el tamaño de la órbita de Marte, no lo es. Un número de doble precisión tiene una precisión de 1 parte en [matemáticas] 2 ^ {54} [/ matemáticas], que es aproximadamente un millón de veces más fino. En el radio completo de la órbita de Marte, puede resolver distancias de aproximadamente 12 micras.
Ahora, cuando navegas en una nave espacial, digamos, haces cálculos relativos en lugar de cálculos absolutos. Estás más preocupado por las cosas en tu vecindad inmediata que por las cosas que están a 1 UA, incluso si tu objetivo está a 1 UA. Puede ser más preciso sobre su objetivo una vez que se acerca a él. Por lo tanto, los números de punto flotante de precisión simple suelen ser más que suficientes para algo así. Para las distancias involucradas en la navegación, la precisión simple le brinda precisión milimétrica o mejor.
Dicho todo esto, el punto flotante binario IEEE 754 no es la mejor opción para todo.
Por ejemplo, las instituciones financieras han construido su aritmética alrededor de la precisión decimal y el redondeo decimal. Esto viene de siglos de manejar los libros a mano, en decimal. Por lo tanto, los cálculos financieros a menudo usan aritmética decimal para que los resultados de la computadora coincidan con lo que se calculó previamente a mano. IEEE 854 (y más tarde, IEEE 754–2008) incluyen disposiciones para coma flotante decimal. Alternativamente, puede escribir funciones aritméticas decimales explícitas sin depender de esos estándares.
Para las aplicaciones que necesitan una precisión mucho mayor, existen muchas bibliotecas que proporcionan operaciones de punto flotante y de precisión arbitraria. Como mencioné anteriormente, la mayoría de las cosas no lo necesitan . Pero, por las pocas cosas que hacen, las bibliotecas están disponibles.
Sin embargo, es posible que se pregunte: “¿Qué pasa con todas estas cosas divertidas que suceden con números simples como 0.1 + 0.2?”
(Fuente: Saturday Morning Breakfast Cereal , una gran tira cómica en línea).
Regrese y vuelva a leer mi declaración sobre la precisión frente a la precisión. Está proporcionando valores con 1 dígito decimal de precisión, por lo que debe interpretar el resultado con solo 1 dígito decimal de precisión.
Internamente, la computadora lleva varios dígitos binarios de precisión. Los valores 0.1 y 0.2 no tienen representaciones exactas en coma flotante binaria, por lo que cuando convierte de decimal a binario y viceversa, puede obtener respuestas que parecen un poco divertidas en decimal.
La respuesta proporcionada, contraintuitivamente es precisa . Simplemente estamos mostrando demasiada precisión en relación con las entradas.
Considere el siguiente programa C:
#include int main () { flotador a = 0.1f; flotador b = 0.2f; flotador c = a + b; flotador d = 0.3f; printf ("% a \ n% a \ n% a \ n% a \ n% 15.12f \ n% 15.12f \ n", a, b, c, d, c, d); devuelve 0; }
El especificador de conversión %a
le dice al compilador que imprima la representación binaria del número de coma flotante. Si lo ejecuta, obtendrá el siguiente resultado:
0x1.99999ap-4 0x1.99999ap-3 0x1.333334p-2 0x1.333334p-2 0.300000011921 0.300000011921
Observe que 0.1f + 0.2f proporciona exactamente el mismo patrón de bits que la constante 0.3f. Es completamente preciso y predecible.
Le da el patrón de punto flotante binario más cercano al valor decimal 0.3. Eso es lo más exacto posible en punto flotante de radios binarios.
Y más que suficiente para llevarte a Marte.