¿Por qué el operador de módulo no funciona para el doble en c #?

Considera esto:

double x,y; x =120.0; y = 0.05; double z= x % y; 

Intenté esto y esperé que el resultado fuera 0, pero salió 0.04933333.

Sin embargo,

 x =120.0; y = 0.5; double z= x % y; 

de hecho dio el resultado correcto de 0.

¿Que está sucediendo aquí?

Math.IEEERemainder(double, double) pero tampoco devuelve 0. ¿Que esta pasando aqui?

Además, como un aparte, ¿cuál es la forma más adecuada de encontrar el rest en C #?

Debido a su formato de almacenamiento, double s no puede almacenar todos los valores exactamente como se ingresa o muestra. La representación humana de los números suele ser en formato decimal, mientras que los double se basan en el sistema dual.

En un double , 120 se almacena precisamente porque es un valor entero. Pero 0.05 no lo es. El doble se aproxima al número más cercano a 0.05 que puede representar. 0.5 es una potencia de 2 ( 1/2 ), por lo que se puede almacenar con precisión y no se produce un error de redondeo.

Para tener todos los números exactamente de la misma manera que lo ingresa / muestra en el sistema decimal, use decimal lugar.

 decimal x, y; x = 120.0M; y = 0.05M; decimal z = x % y; // z is 0 

Podrías hacer algo como:

 double a, b, r; a = 120; b = .05; r = a - Math.floor(a / b) * b; 

Esto debería ayudar;)

Creo que si probara lo mismo con el decimal , funcionaría correctamente.

El módulo solo debe usarse con un número entero. El rest proviene de una división euclidiana. Con doble, puede tener resultados inesperados.

Ver este artículo

http://en.wikipedia.org/wiki/Floating_point#Accuracy_problems puede ayudarlo a comprender por qué obtiene estos resultados “extraños”. Hay una precisión particular que los números de coma flotante pueden tener. Simplemente prueba estas consultas y echa un vistazo a los resultados:

0.5 en base 2

0.05 en base 2