C/Visual C - problema con suma de numeros en Microsoft Visual C

 
Vista:

problema con suma de numeros en Microsoft Visual C

Publicado por Jesus (1 intervención) el 28/08/2002 19:38:46
Duda de \"suma de numeros en Microsoft Visual C++ 6.0\" . Me esta pasando una cosa que no me puedo creer. Resulta que estoy sumando
67,325100 ; 13,124500 ; 25,236520 ; 67,325100 ;13,124500 ;25,236520 ;67,325100 y si lo comparo con
278,69734 me dice que son diferentes. ¿Por que pasa esto? ¿ que tipo de dato debería utilizar en las variables? ( he probado con double y long double) la diferencia es ~ 5 e-14
Valora esta pregunta
Me gusta: Está pregunta es útil y esta claraNo me gusta: Está pregunta no esta clara o no es útil
0
Responder

RE:problema con suma de numeros en Microsoft Visua

Publicado por El Mogur (202 intervenciones) el 28/08/2002 20:28:55
Eso es problema por la precisión de los reales. En realidad los reales se almacenan como número binarios. Al hacer el cambio de base, desde base 10 a base 2, se pierde precisión irremediablemente. De hecho, números que en base 10 son "redondos", en base 2 pasan a ser periódicos puros... y con esos, por ejemplo, por mucho que aumentes la precisión de las variables (poniendo muchos "long" antes del double ;) ), siempre te darán problemas.
Si sumas dos números con los que has perdido precisión al pasar a binario, y luego lo "conviertes" a decimal, ya no será lo mismo.
Para solucionarlo, tienes que hacer las comparaciones entre flotantes "con cuidado", es decir, considerando un umbral:

#define PRECISION .000001
#define ABS(x) (x > 0 ? x : -x)

bool iguales(float a, float b) {
return ABS(a-b) < PRECISION;
}
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:problema con suma de numeros en Microsoft Visua

Publicado por Malandrin (29 intervenciones) el 28/08/2002 23:07:40
Mogur, estás equivocado, un número no pierde precisión por cambiarlo de base (simplemente estás haciendo eso, cambiarlo de base :) en vez de poner 10 para representar el valor 10 pones una A (por ejemplo)). El problema surge no por el cambio de base, sino por la precisión que puede almacenar la variable usada.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:problema con suma de numeros en Microsoft Visua

Publicado por El Mogur (202 intervenciones) el 29/08/2002 18:48:13
No, no, no te confundas...
Tienes razón, un cambio de base no hace perderte precisión... _si el número es entero_ es decir, si no tiene decimales. Como tú muy bien dices, el 10 en base diez lo pones como A en base 16, y no se pierde precisión, y si traduce un número demasiado grande a una variable más pequeña, pues no entra.
Pero en la pregunta original se habla de número _reales_, y ahí sí se pierde precisión al cambiar de base.

Cuando escribimos en base 10 un número, se puede descomponer de la forma: 1234 = 1* 1000 + 2 * 100 + 3 * 10 + 4 * 1, es decir, multiplicando cada dígito por la unidad (10^0), la decena (10^1), centena, (10^2), etc... Cuando ponemos decimales, estamos haciendo lo mismo, pero en vez de elevar la base (10) con números positivos, lo hacemos con números negativos:
0.4321 = 4 * 0.1 + 3 * 0.01 + 2 * 0.001 + 1 * 0.0001.
Hasta aquí de acuerdo, no?
Pues resulta que en Base 2 pasa lo mismo, pero los números por los que lo multiplicas son 0.5, 0.25, 0.125, etc. (2^-1, 2^-2, 2^-3..., es decir 1/2, 1/4, 1/8...).
Y aquí está el problema: existen números en base 10 que no pueden expresarse como una suma de números de la forma 1/2, 1/4, 1/8, 1/16...
Por ejemplo, el número que en base 10 es tan trivial, como 0.3, es periódico! 0.3 (base 10) = 0.0 1001 1001 1001 1001 ...
Por lo tanto, por muy grande que sea el hueco que tienes para la variable, siempre vas a perder precisión, al tratar de representarlo en base 2...
Y eso es lo que le pasa en la pregunta. El primer número que pone, 67.3251 es periódico puro en
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:problema con suma de numeros en Microsoft Visua

Publicado por El Mogur (202 intervenciones) el 29/08/2002 19:07:25
vaya, me he enrollado demasiado, y no ha entrado entera.

Acabo:
Decía que eso es lo que le pasa en la pregunta.
El primer número que pone, 67.3251 que tiene 4 decimales, es periódico puro en base 2, por lo tanto, siempre va a perder precisión.
Este tipo de cosas explican que sumando números de 4 o 5 decimales, de el error en el decimal 14

Espero haberme explicado
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:problema con suma de numeros en Microsoft Visua

Publicado por Anonimo (8 intervenciones) el 29/08/2002 21:09:11
La precisión está limitada a pocos decimales. Se me ocurren tres cosas:

1) Una solución sería crear tus propias liberías de funciones matemáticas
para trabajar con números con muchos decimales. Te llevaría tiempo
hacerlo pero valdría la pena y aprenderías más haciéndolo.

2) Otra solución es buscar librerías matemáticas creadas por otros, existen algunas circulando.

3) Otra solución sería quitar los decimales multiplicando. Por ejemplo,
convertir todos los valores de tipo 'x' a (x * 10000), realizar todas las
operaciones y el resultado final dividirlo (r = r / 10000). Entonces
todas las operaciones se realizarían entre numeros enteros siempre
que den cabida al valor.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar

RE:problema con suma de numeros en Microsoft Visua

Publicado por Alvaro (122 intervenciones) el 03/09/2002 00:01:45
El problema es como representa los punto flotante el compoutador.
recuerdas que 10.4556 es lo mismo que 0.104556 * 10^2. asi lo hace el computador pero en base 2 y no en base 10.
en un float, por ejemplo, que tiene 32 bits, utiliza el bit mas significativo para el signo del numero. los diguientes 8 bits para el exponente ( considerando el signo te da un rango de 127) y los siguientes 23 bits para el valor o mantisa.
el computador.
SEEEEEEEEMMMMMMMMMMMMMMMMMMMMMMM es el numero conde S es el signo, E es el exponente y M la mantisa.
la formula es:
E = MC^2, No, perdon es:
N = (-1)^S * 2 ^ (E - 127) * (1.M)
La razon del 1.M es que el primer bit de la mantisa siempre es uno por lo que no se pone. esto deja los 23 bist para representar un numero de 2 ^ 24.
Ahora, al comparar este tipo de numeros se debe igualñar el exponente. es en este momento en el que pierdes decimales, puesto que uno de los dos números sera cambiado (quisa por operaciones shift).
AMEN.
Valora esta respuesta
Me gusta: Está respuesta es útil y esta claraNo me gusta: Está respuesta no esta clara o no es útil
0
Comentar