Exécution d'une expérience rapide liée à Is double Multiplication Broken in .NET? et lire quelques articles sur la mise en forme de chaîne C#, je pensais que ceci:Mise en forme double pour la sortie en C#
{
double i = 10 * 0.69;
Console.WriteLine(i);
Console.WriteLine(String.Format(" {0:F20}", i));
Console.WriteLine(String.Format("+ {0:F20}", 6.9 - i));
Console.WriteLine(String.Format("= {0:F20}", 6.9));
}
serait le C# équivalent de ce code C:
{
double i = 10 * 0.69;
printf ("%f\n", i);
printf (" %.20f\n", i);
printf ("+ %.20f\n", 6.9 - i);
printf ("= %.20f\n", 6.9);
}
Cependant, le C# produit la sortie:
6.9
6.90000000000000000000
+ 0.00000000000000088818
= 6.90000000000000000000
malgré que je montre égal à la valeur 6.89999999999999946709 (plutôt que 6.9) dans le débogueur.
C par rapport à ce qui montre la précision demandée par le format:
6.900000
6.89999999999999946709
+ 0.00000000000000088818
= 6.90000000000000035527
Que se passe-t-il?
(Microsoft .NET Framework Version 3.51 SP1/Visual Studio C# 2008 Express Edition)
J'ai une formation dans le calcul numérique et expérience dans l'implémentation arithmétique d'intervalle - une technique d'estimation des erreurs en raison des limites de précision dans les systèmes numériques complexes - sur diverses plates-formes. Pour obtenir la prime, n'essayez pas d'expliquer la précision de stockage - dans ce cas, c'est une différence d'un ULP d'un double de 64 bits.
Pour obtenir la prime, je veux savoir comment (ou si) .Net peut formater un double à la précision demandée comme visible dans le code C.
Attend pour moi comme C# est montrant la même précision, juste qu'il traite avec des chiffres beaucoup plus précis que ne C++ ... –
Il est également tout à fait possible que le compilateur C# regarde 10 * 0.69 et se dit "oooh, je sais celui-ci, c'est 6.9!" et sustitutes que dans inplace de faire le calcul à l'exécution –
FWIW - en utilisant 'i' pour une variable double me donne la dissonance cognitive – plinth