2010-09-20 5 views
3

Inspiré par this question, ce qui suit ne fait pas ce que je pense à:Pourquoi certains nombres à virgule flottante sont-ils représentés avec précision en C#?

float myFloat = 0.6; 
Console.WriteLine(myFloat); 
// Output: 0.6 

J'attends ci-dessus pour imprimer 0.60000002384185791 (la représentation en virgule flottante de 0.6) - clairement il y a quelques mécanisme ici qui fait ce travail alors qu'en fait il ne devrait pas (bien que comme vous pouvez le voir de la question liée, il ne fonctionne parfois pas)

Quel est ce mécanisme et comment ça marche?

+0

@NullUserExceptiuon - vrai, je vais modifier le titre. – Justin

+0

La sortie par défaut pour un flottant est de 7 chiffres significatifs. 0.6000000, puis les zéros de fin sont supprimés – adrianm

Répondre

4

Si vous regardez la mise en œuvre de Console.WriteLine, vous verrez qu'il finit par appeler ToString sur la valeur avec une valeur par défaut FormatProvider. C'est à dire. le résultat que vous voyez est la façon dont le numéro apparaît lors du formatage en utilisant ce fournisseur de format.

Bien qu'il n'explique pas les détails de la façon dont le résultat est produit, cela montre que Console.WriteLine passe par un formatage de la valeur avant de l'imprimer.

3

Je suppose que la surcharge WriteLine qui prend un flotteur arrondi fait lors de la conversion en une chaîne ...

+0

Si vous ne voulez pas arrondir, utilisez quelque chose comme ceci: Console.WriteLine (m.ToString ("F8", CultureInfo.InvariantCulture)); où F représente le point fixe Pour plus d'informations, voir http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx#FFormatString –

1

0.6 ne peut pas être représenté sous les flottants IEEE754. Il se situe entre 0.599999964237213134765625 (0x3f199999) et 0.600000083446502685546875 (0x3f19999b). Le mode arrondi au plus proche donne 0,60000002384185791015625 (0x3f19999a), ce qui est imprimé par WriteLine.

Vous devez soit utiliser une représentation en virgule flottante de précision supérieur (double) ou de limiter le nombre de décimales les imprime WriteLine:

float f = 0.6; Console.WriteLine("{0:N6}", f); 
+0

L'OP est au courant de l'inexactitude du flotteur, et se demande pourquoi la sortie ** est ** 0,6 :) – snemarch

Questions connexes