38 votes

L'arrondi décimal C # est-il incohérent?

J'ai été la lutte contre la précision décimale en C# à venir à partir d'un SQL Décimal (38,30) et j'ai enfin fait tout le chemin à un arrondi bizarrerie. Je sais que je suis probablement donnant sur l'évidente ici, mais j'ai besoin d'un peu de perspicacité.

Le problème, je vais avoir, c'est que le C# n'est pas de produire ce que je considère être la cohérence des résultats.

decimal a = 0.387518769125m;
decimal b = 0.3875187691250002636113061835m;

Console.WriteLine(Math.Round(a, 11));
Console.WriteLine(Math.Round(b, 11));
Console.WriteLine(Math.Round(a, 11) == Math.Round(b, 11));

Les rendements

0.38751876912
0.38751876913
False

Heu, 0.38751876913? Vraiment? Ce qui me manque ici?

À partir de MSDN:

Si les chiffres dans les décimales de position est impair, il est modifié pour un même chiffre. Sinon, il est laissé inchangé.

Pourquoi suis-je voir des résultats incohérents? Une telle précision n'est pas en changeant le 'chiffre dans le nombre de décimales position"...

45voto

Jason Points 125291

À partir de MSDN:

Si il y a un seul non-zéro chiffre en d à la droite de l' decimals la position du point décimal , et sa valeur est 5, du chiffre dans le nombre de décimales position est arrondi vers le haut si elle est impaire, ou reste inchangé si on est même. Si d a moins de chiffres fractionnaires qu' decimals, dest retourné à l'identique.

Dans ton premier cas

decimal a = 0.387518769125m;
Console.WriteLine(Math.Round(a, 11));

il est un seul chiffre à la droite de la 11e place, et de ce nombre est 5. Par conséquent, depuis le 11 position est la même, il est laissé inchangé. Ainsi, vous obtenez

0.38751876912

Dans votre second cas

decimal b = 0.3875187691250002636113061835m;
Console.WriteLine(Math.Round(b, 11));

il n'est pas un seul chiffre à la droite de la 11ème place. Par conséquent, ce est vers le haut grade de l'école-de l'arrondissement; autour de vous si le chiffre suivant est égal ou inférieur à 4, sinon vous arrondir. Car le chiffres à droite de la 11ème place est de plus de 4 (c'est à 5), nous arrondissons donc, vous voyez

0.38751876913

Pourquoi suis-je voir des résultats incohérents?

Vous n'êtes pas. Les résultats sont tout à fait conformes à la documentation.

26voto

Oded Points 271275

À partir de MSDN - Mathématiques.Tour De Méthode (Décimal, Int32):

Si il y a un seul non-zéro chiffre d à la droite de la décimales décimales position et sa valeur est égale à 5, le chiffre dans le nombre de décimales position est arrondi vers le haut si elle est impaire, ou reste inchangé si c'est la même. Si d a moins de chiffres fractionnaires de décimales, d est retourné à l'identique.

Le comportement de cette méthode suit la Norme IEEE 754, section 4. Ce type d'arrondi est parfois appelé d'arrondi au plus près, ou de l'arrondi. Il minimise les erreurs d'arrondi qui résultent de façon constante, arrondir une valeur médiane dans une seule direction.

Notez l'utilisation de la non-chiffre zéro. Cela correspond à vos premiers exemples, mais pas la deuxième.

Et:

Pour contrôler le type d'arrondi utilisé par le Tour(en Décimal, Int32), la méthode, l'appel de la Virgule.Ronde(Décimal, Int32, MidpointRounding) de surcharge.

4voto

Albin Sunnanbo Points 30722

La partie "chiffre unique non nul en d à droite de la position décimale décimale et dont la valeur est 5" explique le résultat. Ce n'est que lorsque la partie à arrondir est exactement 0,5 que la règle d'arrondi entre en jeu.

4voto

Passons les deux nombres de plus de 11 chiffres à gauche:

38751876912.5
38751876912.50002636113061835

En arrondissant le banquier, nous arrondissons le premier. Sous chaque système d'arrondi du milieu, nous arrondissons le deuxième chiffre vers le haut (car il n'est pas au milieu) .

.Net fait exactement ce à quoi nous nous attendions.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X