2011-12-15 4 views
4

J'ai une application écrite en Microsoft Visual C++ 6.0. Maintenant, j'ai réécrit l'application dans Visual Studio 2010 en utilisant C#, mais les résultats ne correspondent pas en raison de problèmes de précision. L'un de ces problèmes de précision est le suivant.Problèmes de précision avec Visual Studio 2010

float a = 1.0f; 

float b = 3.0f; 

float c = a/b; 

Ceci est le code C# lorsqu'il est exécuté dans Visual Studio 2010 donne c valeur = 0.333333343

Mais le même code, la suppression f après la valeur dans la définition de la valeur, lorsqu'il est exécuté sur Visual C++ 6.0 donne la valeur c = 0.333333.

Quelqu'un peut-il le trier et expliquer la façon d'avoir la même valeur pour c dans Visual Studio ainsi que dans Visual C++ 6.0 ??


En fait, les valeurs sont extraites de la fenêtre de surveillance. Je suis venu à savoir que les différentes versions de Visual Studio peuvent différer dans la représentation en format virgule flottante. Par conséquent, les valeurs en veille peuvent ne pas être utiles. C'est la raison pour laquelle j'ai imprimé les valeurs dans les deux versions de Visual Studio et les résultats sont les suivants. avec Visual Studio 6.0 en utilisant visual C++ langue, il est 0,333333 (six 3 années)

mais avec Visual Studio 10 en utilisant le langage C# est 0,3333333 (sept 3 années)

Alors quelqu'un peut-il me aider à faire mon programme C# produire le même résultat que visuel C++ ??? (comment puis-je faire des opérations flottantes pour produire les mêmes résultats sur les deux versions ???)

+2

Comment regardez-vous les valeurs? la représentation interne est la même (à moins que je ne me trompe et que C# utilise le «double» dans les coulisses), mais les méthodes de montrer un nombre à l'utilisateur diffèrent, ainsi vous pourriez simplement regarder différents affichages par défaut. –

+0

@MrLister la spécification C# 4.0 indique dans la section 4.1.6 qu'une opération binaire sur les flottants "est effectuée en utilisant * au moins *' float' plage et de précision "(soulignement ajouté). La précision dans les coulisses est donc définie par l'implémentation. Le .NET Framework peut très bien utiliser les doubles dans les coulisses. – phoog

Répondre

15

Étant donné que la valeur exacte est 0,3 récurrente, aucun d'entre eux est "correct" - et si vous essayez de match exact résultats de calculs binaires à virgule flottante, c'est généralement une mauvaise idée pour commencer à cause de la façon dont ils fonctionnent. (Voir mon article sur binary floating point in .NET pour un peu plus d'informations).

Il est possible que vous ne devriez pas utiliser binaire en virgule flottante en premier lieu (par exemple, si vos valeurs représentent exactement, les montants artificiels tels que l'argent). Alternativement, il est possible que vous devriez seulement faire des comparaisons d'égalité avec une tolérance particulière.

Il est également possible que C# et C produisent le même schéma binaire exact - mais vous voyez des résultats différents en raison de la façon dont ces valeurs sont formatées. Encore une fois, je n'utiliserais pas la représentation textuelle des nombres pour les comparaisons.

+0

J'ai imprimé les deux valeurs, avec le C++ visuel donnant 0,333333 (six 3) et avec C# donnant 0,3333333 (sept 3). Cela signifie qu'il y a une erreur dans cela. Comment puis-je faire Visual C++ 6.0 et Visual Studio 10 avec C# produire les mêmes résultats ?? – Mahesh

+0

@Mahesh: Non, cela ne veut pas dire qu'il y a une erreur. Je soupçonne que c'est juste le texte fornatting impliqué dans chaque cas. –

5

C# affiche simplement moins de décimales. 0.333333343 arrondi à six chiffres significatifs est 0.333333. La valeur sous-jacente de c est la même.

Bien sûr, si vous voulez plus de précision, vous pouvez toujours utiliser les variables double.

3

Le point flottant C# peut être géré par les types float et double. Un float type a une précision de 7 chiffres et un double 16.

Je crois que la précision standard C++ est d'environ 16 chiffres (15.9 en moyenne!).

Dans tous les cas, aucune représentation n'est arithmétiquement correcte car 1/3 est 0,333 récurrent.

Je pense que c'est simplement la représentation de la valeur que vous voyez (sachez que le débogueur convertira la valeur en une chaîne pour l'affichage.) Si vous vérifiez les emplacements de mémoire pour chacun, vous trouverez probablement que les valeurs

1

Une vérification rapide révèle que oui, les chiffres sont exactement les mêmes, alors la réponse à votre question est: quand vous voulez la même sortie, tout ce que vous devez faire est de vous assurer que les méthodes d'affichage sont compatibles Par exemple, printf("%9.7f", result) en C et string.Format("{0:0.0000000}", result) en C# C'est tout

Questions connexes