2010-04-06 9 views
3

Je vois une situation intrigante arrondissant la devise en C# (VS 2008 SP1). Ci-dessous une image des cas de test:C# Mise en forme Monnaie

alt text http://img697.imageshack.us/img697/8500/testcases.png

j'attendais cas cinq, six et sept (mon mauvais sur pas les numérotant dans la sortie) pour arrondir le nombre à un sou.

Voici mon code de test:

static void Main(string[] args) 
{ 
    decimal one = 10.994m; 
    decimal two = 10.995m; 
    decimal three = 1.009m; 
    decimal four = 0.0044m; 
    decimal five = 0.0045m; 
    decimal six = 0.0046m; 
    decimal seven = 0.0049m; 
    decimal eight = 0.0050m; 

    Console.WriteLine(one + ": " + one.ToString("C")); 
    Console.WriteLine(two + ": " + two.ToString("C")); 
    Console.WriteLine(three + ": " + three.ToString("C")); 
    Console.WriteLine(four + ": " + four.ToString("C")); 
    Console.WriteLine(five + ": " + five.ToString("C")); 
    Console.WriteLine(six + ": " + six.ToString("C")); 
    Console.WriteLine(seven + ": " + seven.ToString("C")); 
    Console.WriteLine(eight + ": " + eight.ToString("C")); 

    Console.ReadLine(); 
} 

Quand je réfléchissais dans .ToString (format string) pour voir ce qui se passait, j'ai trouvé

public string ToString(string format) 
{ 
    return Number.FormatDecimal(this, format, NumberFormatInfo.CurrentInfo); 
} 

qui a l'appel à

[MethodImpl(MethodImplOptions.InternalCall)] 
public static extern string FormatDecimal(
    decimal value, 
    string format, 
    NumberFormatInfo info); 

Y at-il une logique dans cet appel qui indique la granularité de mes paramètres de culture actuels pour NumberFormatInfo i s deux décimales pour currencty alors ne laissez pas la place dix millièmes rouler le numéro parce qu'il est insignifiant?

Comment cette méthode est-elle implémentée? Sommes-nous en train de faire du «bit shift land» ou y a-t-il autre chose?

Merci pour toute Insights.

+0

Si vous voulez vraiment des cas 5, 6, 7 à arrondir à un sou, vous devez d'abord autour d'un demi-sou: Math.Round (cinq, 3, MidpointRounding.AwayFromZero): Le résultat de ceci arrondira à un penny. –

+0

Trouvez une culture qui mesure les millidollars et vous serez justifié. –

+1

"Ah non, vous ne comprenez pas, c'est très compliqué, c'est un agrégat, donc je parle de fractions de centimes ici, et avec le temps ça rajoute beaucoup." http://www.imdb.com/title/tt0151804/quotes?qt0996772 – blu

Répondre

8

Suivant les principes mathématiques de base, les cas 4, 5, 6 et 7 ne devraient pas arrondir à un cent. Vous ne pouvez pas arrondir en commençant par le nombre le plus à droite et en arrondissant au chiffre supérieur. Vous ne regardez qu'un chiffre à droite du numéro que vous voulez arrondir.

http://www.enchantedlearning.com/math/rounding/

l'ordinateur est en train d'exécuter les mathématiques de base, comme ils sont censés le faire.

Edition - a ajouté

un meilleur lien: http://math.about.com/od/arithmetic/a/Rounding.htm

+0

Intéressant, que diriez-vous du cas 1 alors? – blu

+0

Dans le cas 1, le dernier chiffre forcerait les 9 derniers à arrondir. Puisque 9 + 1 = 10, alors les 9 suivants doivent y avoir 1 ajouté, et puisque c'est un 9 ... – David

+0

OK, donc nous disons que nous sommes en train d'arrondir à la centième place, alors regardez seulement le nombre directement à droite. OK, bonne réponse, merci. – blu