Selon la documentation, la méthode decimal.Round
utilise un algorithme rond qui n’est pas commun à la plupart des applications. Donc, je finis toujours par écrire une fonction personnalisée pour faire l’algorithme plus rond et 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; }
Est-ce que quelqu’un connaît la raison de cette décision de conception du cadre?
Existe-t-il une implémentation intégrée de l’algorithme Round-Half-Up dans la structure? Ou peut-être une API Windows non gérée?
Cela pourrait être trompeur pour les débutants qui écrivent simplement decimal.Round(2.5m, 0)
attend 3 comme résultat, mais obtenir 2 à la place.
Probablement parce que c’est un meilleur algorithme. Au cours de nombreux arrondis effectués, vous aurez la moyenne que tous les 0,5 sont arrondis de manière égale. Cela donne de meilleures estimations des résultats réels si vous êtes par exemple, en ajoutant un groupe 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.
Les autres réponses aux raisons pour lesquelles l’algorithme du banquier (alias round half to even ) est un bon choix sont tout à fait correctes. Il ne souffre pas d’un biais négatif ou positif autant que de la méthode du demi-tour de zéro par rapport à la plupart des dissortingbutions raisonnables.
Mais la question était de savoir pourquoi .NET utilisait par défaut l’arrondi de Banker – et la réponse est que Microsoft a suivi la norme IEEE 754 . Ceci est également mentionné dans MSDN pour Math.Round sous remarques.
Notez également que .NET prend en charge la méthode alternative spécifiée par IEEE en fournissant l’énumération MidpointRounding
. Ils auraient bien sûr pu fournir plus d’alternatives à la résolution de problèmes de liens, mais ils choisissent simplement de satisfaire à la norme IEEE.
Bien que je ne puisse pas répondre à la question “Pourquoi les concepteurs de Microsoft ont-ils choisi cette option par défaut?”, Je tiens simplement à souligner qu’une fonction supplémentaire est inutile.
Math.Round
vous permet de spécifier un MidpointRounding
:
Les décimales sont principalement utilisées pour l’ argent ; l’arrondissement des banquiers est fréquent lorsque l’on travaille avec de l’ argent . Ou vous pourriez dire.
Ce sont surtout les banquiers qui ont besoin du type décimal; par conséquent, il fait «l’arrondissement des banquiers»
L’arrondi des banquiers a l’avantage qu’en moyenne vous obtiendrez le même résultat si vous:
L’arrondi avant l’ajout a permis d’économiser beaucoup de travail dans les jours précédant les ordinateurs.
(Au Royaume-Uni, lorsque les banques décimales ne fonctionnaient pas à mi-temps, il restait encore beaucoup de pièces de monnaie pour un demi-penny et les prix se terminaient souvent à moitié pence – donc beaucoup d’arrondis)
Utilisez une autre surcharge de la fonction Round comme ceci:
decimal.Round(2.5m, 0,MidpointRounding.AwayFromZero)
Il va sortir 3 . Et si vous utilisez
decimal.Round(2.5m, 0,MidpointRounding.ToEven)
vous obtiendrez l’arrondi du banquier.