Problema con metodo Equal para tipos double.

11/03/2005 - 11:34 por Kiko Llan | Informe spam
Hola,

Estoy teniendo problemas para comprender los resultados
del metodo equal (operador ==) sobre tipos double. A
continuación incluyo un codigo sencillo de ejemplo:

[STAThread]
static void Main(string[] args)
{
double a1=1;
double b1=-1.1;
Console.WriteLine(a1+b1);
Console.WriteLine(-0.1);
Console.WriteLine(-0.1==a1+b1); //sentencia 1
Console.WriteLine((-0.1-a1-b1)==0); //sentencia 2
}

Resultados por consola:
-0,1
-0,1
False
True

Esperaba que la sentencia 1 diese como resultado true,
pero no es asi. En cambio, la sentencia 2 si que resulta
cierta.

¿Cual es el problema? ¿Como debo interpretar el operador
==?. He hecho pruebas mostrando los HashCode y se obtienen
los mismo resultados.

Muchas gracias de antemano,

Kiko

Preguntas similare

Leer las respuestas

#1 A.Poblacion
11/03/2005 - 18:08 | Informe spam
"Kiko Llan" wrote in message
news:5c4501c52625$f9423b80$
Estoy teniendo problemas para comprender los resultados
del metodo equal (operador ==) sobre tipos double.
[...]
Esperaba que la sentencia 1 diese como resultado true,
pero no es asi. En cambio, la sentencia 2 si que resulta
cierta.
¿Cual es el problema? ¿Como debo interpretar el operador
==?



El problema es que los números de coma flotante (float o double) no son
exactos, sino aproximaciones. Por ejemplo, puede que tú le introduzcas a un
double el valor 0.3 y el sistema lo almacene como 0.299999999999999999.
Cuando lo visualizas te redondea los decimales y aparenta ser 0.3, pero el
valor binario que hay dentro no es el que piensas. En cuanto haces
operaciones aritméticas con ellos, estos errores se van generando y
acumulando internamente, de forma que cuando comparas el resultado final, no
tiene el valor exacto que esperabas.

¿El remedio? Primera alternativa: No usar nunca el operador == entre
"float" o "double". Si necesitas aritmética exacta, usa el tipo "decimal".
Segunda alternativa:
double a=.., b=...;
if (a==b) ... //Esto puede dar resultados inesperados.
if (Math.Abs(a-b)<0.000000001) ... //Esto funcionará razonablemente bien
si pones una constante adecuada.
Respuesta Responder a este mensaje
#2 Octavio Hernandez
11/03/2005 - 23:00 | Informe spam
Kiko,

Los valores double se almacenan en un formato BINARIO sobre 8 bytes
(estándar IEEE 754). 0.1 es el ejemplo típico de un valor que en decimal se
representa exactamente pero en binario no se puede. O sea, que como te dice
Alberto, cuando escribas en tu programa la constante 0.1, en realidad
tendrás algo así como 0.09999999998 ó 0.10000000007 (el double garantiza una
precisión de unos 10-11 dígitos DECIMALES). A partir de ahí, todo lo que en
sistema decimal te parece una verdad absoluta en binario puede no serlo.
Específicamente, nunca se deben comparar con = dos números de punto
flotante, sino que se debe comprobar si su diferencia en valor absoluto no
supera cierto "epsilon", como indica Alberto.

Por ejemplo, para el trabajo con cantidades monetarias el funcionamiento de
la aritmética de punto flotante puede ser fatal. Por eso .NET ofrece el tipo
básico System.Decimal, que permite representar directamente las cifras
decimales que componen un número en vez de convertirlo a binario. La
aritmética sobre datos de tipo Decimal es más lenta, pero muchísimo más
exacta.

Slds,

Octavio

"Kiko Llan" escribió en el mensaje
news:5c4501c52625$f9423b80$

Hola,

Estoy teniendo problemas para comprender los resultados
del metodo equal (operador ==) sobre tipos double. A
continuación incluyo un codigo sencillo de ejemplo:

[STAThread]
static void Main(string[] args)
{
double a1=1;
double b1=-1.1;
Console.WriteLine(a1+b1);
Console.WriteLine(-0.1);
Console.WriteLine(-0.1=¡+b1); //sentencia 1
Console.WriteLine((-0.1-a1-b1)==0); //sentencia 2
}

Resultados por consola:
-0,1
-0,1
False
True

Esperaba que la sentencia 1 diese como resultado true,
pero no es asi. En cambio, la sentencia 2 si que resulta
cierta.

¿Cual es el problema? ¿Como debo interpretar el operador
==?. He hecho pruebas mostrando los HashCode y se obtienen
los mismo resultados.

Muchas gracias de antemano,

Kiko
Respuesta Responder a este mensaje
#3 KikoLlan
14/03/2005 - 09:53 | Informe spam
¡Gracias por las respuestas!

Ya me queda claro donde esta mi problema. Estudiare la
posibilidad de usar el tipo decimal o usare un valor
epsilon para realizar la comparación.

Un saludo y gracias de nuevo,

Kiko



Hola,

Estoy teniendo problemas para comprender los resultados
del metodo equal (operador ==) sobre tipos double. A
continuación incluyo un codigo sencillo de ejemplo:

[STAThread]
static void Main(string[] args)
{
double a1=1;
double b1=-1.1;
Console.WriteLine(a1+b1);
Console.WriteLine(-0.1);
Console.WriteLine(-0.1=¡+b1); //sentencia 1
Console.WriteLine((-0.1-a1-b1)==0); //sentencia 2
}

Resultados por consola:
-0,1
-0,1
False
True

Esperaba que la sentencia 1 diese como resultado true,
pero no es asi. En cambio, la sentencia 2 si que resulta
cierta.

¿Cual es el problema? ¿Como debo interpretar el operador
==?. He hecho pruebas mostrando los HashCode y se obtienen
los mismo resultados.

Muchas gracias de antemano,

Kiko
.

email Siga el debate Respuesta Responder a este mensaje
Ads by Google
Help Hacer una preguntaRespuesta Tengo una respuesta
Search Busqueda sugerida