2008-10-30 18 views
25

He oído hablar de "error" al usar variables de coma flotante. Ahora estoy tratando de resolver este rompecabezas y creo que estoy obteniendo un error de redondeo/punto flotante. Así que finalmente voy a descubrir los conceptos básicos del error de coma flotante.¿Qué es un ejemplo simple de error de coma flotante/redondeo?

¿Qué es un ejemplo simple de error de coma flotante/redondeo (preferiblemente en C++)?

Editar: Por ejemplo, decir que tengo un evento que tiene probabilidad p de tener éxito. Hago este evento 10 veces (p no cambia y todas las pruebas son independientes). ¿Cuál es la probabilidad de exactamente 2 pruebas exitosas? Tengo este código como:

double p_2x_success = pow(1-p, (double)8) * pow(p, (double)2) * (double)choose(8, 2); 

¿Es esta una oportunidad para el error de coma flotante?

+0

creo que lo que realmente necesita es la siguiente: [Lo que todo informático debe saber sobre la aritmética de punto flotante] (http://docs.sun.com/source/ 806-3568/ncg_goldberg.html). – Patrick

+0

Lea esto: http://blog.frama-c.com/index.php?post/2013/05/02/nearbyintf1 –

+0

Vea el ejemplo simple de Java, shuld sea el mismo en C: http://stackoverflow.com/ a/15790782/254109 – xmedeko

Respuesta

9

Generalmente, el error de punto flotante se refiere a cuando un número que no se puede almacenar en la representación de punto flotante IEEE.

Los enteros se almacenan con el bit de la derecha siendo 1, y cada bit a la izquierda es el doble (2,4,8, ...). Es fácil ver que esto puede almacenar cualquier número entero hasta 2^n, donde n es el número de bits.

La mantisa (parte decimal) de un número de coma flotante se almacena de una manera similar, pero moviéndose de izquierda a derecha, y cada bit sucesivo es la mitad del valor de la anterior. (En realidad es un poco más complicado que esto, pero lo hará por ahora).

Por lo tanto, los números como 0.5 (1/2) son fáciles de almacenar, pero no todos los números < 1 se pueden crear agregando un número fijo de fracciones de la forma 1/2, 1/4, 1/8, ...

Un ejemplo realmente simple es 0.1 o 1/10. Esto se puede hacer con una serie infinita (que en realidad no me molesto hacer ejercicio), pero cada vez que una computadora almacena 0.1, no se almacena exactamente este número.

Si usted tiene acceso a una máquina Unix, es fácil de ver esto:.

Python 2.5.1 (r251:54863, Apr 15 2008, 22:57:26) 
[GCC 4.0.1 (Apple Inc. build 5465)] on darwin 
Type "help", "copyright", "credits" or "license" for more information. 
>>> 0.1 
0.10000000000000001 
>>> 

Usted querrá tener mucho cuidado con los tests de igualdad con los flotadores y dobles, en el idioma que usted está en

(En cuanto a su ejemplo, 0.2 es otro de esos números molestos que no se pueden almacenar en IEEE binario, pero mientras prueba desigualdades, en lugar de igualdades, como p < = 0.2, estará bien .)

5

Una C simple que caug Me ht hace un tiempo,

char *c = "90.1000"; 
double d = 0; 
sscanf(c,"%f",&d); 
printf("%0.4f",d); 

>> 90.0999 

Esto fue en una función que convierte ángulos en radianes a DMS, que no lo hicieron en el caso anterior.

+2

Como señaló un usuario anónimo, con 'sscanf' el especificador de conversión" f "requiere un argumento' float', no un 'double' (sin embargo," f "significa' double' a 'printf' - - Sí, es confuso). El especificador de conversión modificado "lf" se debe usar para hacer que 'sscanf' funcione con un' double'. –

26
for(double d = 0; d != 0.3; d += 0.1); // never terminates 
19

imagen vale más que mil palabras - tratan de llamar la ecuación f(k):
enter image description here
y obtendrá tales gráfico XY (X e Y están en escala logarítmica).
enter image description here
Si la computadora puede representar flotadores de 32 bits sin error de redondeo, entonces por cada k deberíamos obtener cero. Pero en su lugar el error aumenta con valores mayores de k debido a la acumulación de error de punto flotante.

hth!

3

Aquí hay uno que me atrapó.

round(256.49999) == 256 
roundf(256.49999) == 257 

dobles y flotadores ..

Cuestiones relacionadas