Así que estoy tratando de averiguar por qué el operador de módulo está devolviendo un valor inusual tan grande.Aritmética de coma flotante - Operador de módulo en el tipo doble
Si tengo el código:
double result = 1.0d % 0.1d;
que dará un resultado de 0.09999999999999995
. Yo esperaría un valor de 0
Nota: este problema no existe con el operador de división - double result = 1.0d/0.1d;
dará un resultado de 10.0
, lo que significa que el resto debe ser 0
.
Déjeme ser claro: no me sorprende que exista un error, me sorprende que el error sea tan grande en comparación con los números en juego. 0.0999 ~ = 0.1 y 0.1 tiene el mismo orden de magnitud que 0.1d
y solo un orden de magnitud de 1.0d
. No es como se puede comparar con un double.epsilon, o decir "es igual si es < 0,00001 diferencia".
He leído sobre este tema en StackOverflow, en las siguientes publicaciones onetwothree, entre otros.
¿Alguien puede sugerir que explique por qué este error es tan grande? Cualquier sugerencia para evitar tener problemas en el futuro (sé que podría usar decimal en su lugar, pero me preocupa el rendimiento de eso).
Editar: Debo señalar específicamente que sé que es un 0,1 infinitely repeating series of numbers in binary - ¿Tiene eso algo que ver con eso?
0.1000000000000000055511151231257827021181583404541015625, para ser exactos. – dan04
Aprecio el recorrido del cálculo. Una aclaración: mencionas "desde 0 = 0.1 mod 0.1, el error real en el mod es 0.1 - 0.09999999 ... - muy pequeño". Estoy confundido porque mi resultado fue 0.099999, pero el resultado real es 0. ¿Cómo es el error real 0.1 - 0.099999? ¿Puede desglosar el cálculo de error de esta parte con un poco más de detalle? – CrimsonX
para responder el comentario anterior para futuros lectores: la sección Editar lo responde. (breve explicación: el error es grande debido a la inestabilidad del mod (función de abolladuras) un ligero aumento en 'a' (por ejemplo, 10.0001) hará que el resultado caiga a cerca de 0) –