¿Por qué .NET utiliza el redondeo bancario por defecto?
Según la documentación, el decimal.Round
método utiliza un algoritmo de redondeo a par que no es común para la mayoría de las aplicaciones. Así que siempre termino escribiendo una función personalizada para hacer el algoritmo de redondeo a la mitad más natural:
public static decimal RoundHalfUp(this decimal d, int decimals)
{
if (decimals < 0)
{
throw new ArgumentException("The decimals must be non-negative",
"decimals");
}
decimal multiplier = (decimal)Math.Pow(10, decimals);
decimal number = d * multiplier;
if (decimal.Truncate(number) < number)
{
number += 0.5m;
}
return decimal.Round(number) / multiplier;
}
¿Alguien sabe el motivo de esta decisión de diseño del marco?
¿Existe alguna implementación incorporada del algoritmo de redondeo a la mitad en el marco? ¿O tal vez alguna API de Windows no administrada?
Podría ser engañoso para los principiantes que simplemente escriben decimal.Round(2.5m, 0)
esperando 3 como resultado pero obteniendo 2 en su lugar.
Las otras respuestas con razones por las cuales el algoritmo del banquero (también conocido como redondear la mitad a igual ) es una buena opción son bastante correctas. No sufre tanto sesgo negativo o positivo como el método de la mitad redondeada desde cero en la mayoría de las distribuciones razonables.
Pero la pregunta era por qué .NET utiliza el redondeo real de Banker de forma predeterminada, y la respuesta es que Microsoft ha seguido el estándar IEEE 754 . Esto también se menciona en MSDN para Math.Round en Comentarios.
Tenga en cuenta también que .NET admite el método alternativo especificado por IEEE al proporcionar la MidpointRounding
enumeración. Por supuesto, podrían haber proporcionado más alternativas para resolver los problemas, pero optaron por cumplir únicamente con el estándar IEEE.
Probablemente porque es un algoritmo mejor. En el transcurso de muchos redondeos realizados, promediará que todos los .5 terminen redondeándose igualmente hacia arriba y hacia abajo. Esto proporciona mejores estimaciones de los resultados reales si, por ejemplo, suma un montón de números redondeados. Yo diría que, aunque no es lo que algunos podrían esperar, probablemente sea lo más correcto.