Selon la documentation, la decimal.Round
méthode utilise un algorithme d'arrondi à égal qui n'est pas courant pour la plupart des applications. Donc je finis toujours par écrire une fonction personnalisée pour faire l'algorithme arrondi plus naturel:
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;
}
Quelqu'un connaît-il la raison de cette décision de conception du cadre?
Existe-t-il une implémentation intégrée de l'algorithme demi-tour dans le cadre? Ou peut-être une API Windows non gérée?
Il pourrait être trompeur pour les débutants qui écrivent simplement en decimal.Round(2.5m, 0)
s'attendant à 3, mais en obtenant 2 à la place.
Réponses:
Probablement parce que c'est un meilleur algorithme. Au cours de nombreux arrondis effectués, vous aurez la moyenne que tous les 0,5 finissent par arrondir également de haut en bas. Cela donne de meilleures estimations des résultats réels si vous êtes, par exemple, en ajoutant un tas de nombres arrondis. Je dirais que même si ce n'est pas ce à quoi certains peuvent s'attendre, c'est probablement la chose la plus correcte à faire.
la source
Les autres réponses avec les raisons pour lesquelles l'algorithme du banquier (aka demi-rond à égal ) est un bon choix sont tout à fait correctes. Il ne souffre pas autant de biais négatif ou positif que la méthode arrondie à moitié de zéro sur la plupart des distributions raisonnables.
Mais la question était de savoir pourquoi .NET utilise l'arrondi réel de Banker par défaut - et la réponse est que Microsoft a suivi la norme IEEE 754 . Cela est également mentionné dans MSDN for Math.Round sous Remarques.
Notez également que .NET prend en charge la méthode alternative spécifiée par IEEE en fournissant l'
MidpointRounding
énumération. Ils auraient bien sûr pu fournir plus d'alternatives à la résolution des liens, mais ils choisissent simplement de respecter la norme IEEE.la source
Bien que je ne puisse pas répondre à la question «Pourquoi les concepteurs de Microsoft ont-ils choisi cette option par défaut?», Je veux juste souligner qu'une fonction supplémentaire n'est pas nécessaire.
Math.Round
vous permet de spécifier unMidpointRounding
:la source
Les décimales sont principalement utilisées pour l' argent ; l'arrondissement bancaire est courant lorsque l'on travaille avec de l' argent . Ou vous pourriez dire.
L'arrondi bancaire a l'avantage qu'en moyenne vous obtiendrez le même résultat si vous:
L'arrondi avant l'addition a permis d'économiser beaucoup de travail les jours précédant les ordinateurs.
(Au Royaume-Uni, lorsque nous sommes allés aux banques décimales, les demi-pence ne pouvaient pas être traitées, mais pendant de nombreuses années, il restait une pièce de demi-pence et le magasin avait souvent des prix se terminant en demi-pence - donc beaucoup d'arrondis)
la source
Decmial
oui. Décimales, non. Pour la postérité, je suis d'accord avec le sentiment d'origine ici.Utilisez une autre surcharge de la fonction Round comme celle-ci:
Il affichera 3 . Et si vous utilisez
vous obtiendrez l'arrondissement bancaire.
la source