Pregunta

double a = 18.565
return Math.Round(a,2)

.. rendimientos 18.57.
Para cualquier otro número Probé el banquero de redondeo funcionó como se esperaba, por ejemplo Math.Round (2.565,2) devuelve 2,56.

Cualquier idea de por qué y cuando eso sucede? Se it error o me estoy perdiendo algo de redondeo bancario?

Gracias ..

¿Fue útil?

Solución

Como Mateo dijo, 18.565 no se puede representar con precisión. El valor real utilizado es 18.565000000000001278976924368180334568023681640625 (que se encuentra usando DoubleConverter ), que es claramente más allá de media -camino. Ahora tengo la sensación de que a escondidas a veces Math.Round consideraremos un valor que es realmente más allá del punto a mitad de camino, pero que es lo más cercano a la mitad del camino como se puede representar con precisión, exactamente como a ese punto. Sin embargo, no he visto ninguna documentación que describe las situaciones en las que que se aplica, y está claro que no está ocurriendo en este caso. No me gustaría que confiar en él.

Incluso el valor redondeado no es exactamente 18,57 por supuesto. En realidad es 18,57000000000000028421709430404007434844970703125.

En el fondo, si realmente, realmente se preocupan por representar los valores decimales con precisión, usted debe estar usando decimal. Eso no es sólo en términos de Math.Round -. Va a todos los aspectos del tratamiento de los valores de coma flotante

Eso hace dar el valor adecuado para Math.Round, por supuesto:

decimal m = 18.565m;
Console.WriteLine(Math.Round(m, 2)); // Prints 18.56

Otros consejos

18.565 no se puede representar exactamente como un doble. Por lo tanto, la representación binaria es un poco más alto, por lo que redondea hacia arriba. Si utiliza decimales:

decimal a = 18.565m;
return Math.Round(a,2)

Se puede representar con exactitud, y no tendrá este problema.

Mi suposición es que los medios de representación de PF no es en realidad un trailing 5; los peligros de FP!

Esto funciona bien, sin embargo:

        decimal a = 18.565M; // <===== decimal
        var s = Math.Round(a, 2);

Doble es un valor de coma flotante, así que tal vez si se escribe como 18.565, en realidad es algo así como en la memoria 18,56500000000000000000000000000000001, y por lo tanto es más que el punto medio.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top