El operador módulo (%) de C# no funciona para valores de tipo double

Hace poco me he encontrado con el siguiente problema utilizando el operador módulo (%) en C# para averiguar si un número es múltiplo de otro.
Si ejecutamos el siguiente fragmento de código en C#
double x, y, z;
x = 3000;
y = 3;
z = x % y;
… obtenemos (como cabría esperar) el resultado z = 0, es decir x es múltiplo de y.
Sin embargo, si ejecutamos este otro código …
double x, y, z;
x = 3000;
y = 0.03;
z = x % y;
… el resultado es z = 0.00000000000011102230246251565 . El resultado no es 0, lo que indicaría que 3000 no es múltiplo de 0.03 y sin embargo eso es incorrecto.
La explicación es la siguiente. Los números en punto flotante (single y double) se almacenan como fracciones binarias, es decir, no pueden almacenar de forma exacta un valor que no sea una fracción binaria. Por ejemplo 0,5 (=1/2) sí se puede almacenar de forma exacta mientras que 0.3 (=3/10) no. Debido a esta imprecisión, el operador módulo puede no devolver el resultado esperado cuando uno de los operandos es en punto flotante.
La solución es utilizar variables de tipo decimal, que no utilizan la representación en punto flotante.
decimal x, y, z;
x = 3000;
y = 0.03;
z = x % y;
Donde el resultado sí es el esperado: z = 0.
Nuestra puntuación
Twittear
Compartir
Compartir
Pin