2017-07-28 13 views
2

J'ai un scénario dans .net (4.6.1) où l'analyse d'une représentation sous forme de chaîne d'une valeur à virgule flottante 6dp produit des résultats différents dans 32 et mode 64 bits.Problème d'analyse double 64 bits 32 bits avec le spécificateur de formatage aller-retour "R"

[Fact] 
public void ParseTest() 
{ 
    var numText = "51.580133"; 
    double.Parse(numText) 
     .ToString("R") 
     .Should().Be(numText); 
} 

Ce test passe en mode 32 bits, mais pour mode 64 bits échoue le texte généré est: « 51,580132999999996 »

Je vous attendriez des problèmes d'arrondi comme celui-ci avec des nombres irrationnels ou des chiffres obtenus au moyen d'un équation, mais il n'y a pas d'ambiguïté sur la longueur et la précision du point flottant ici.

Cela fait partie d'un système plus ancien, donc tout changer en décimal nécessiterait un effort significatif.

Questions:

  1. Pourquoi cela?
  2. Quelles sont les options pour arrondir/tronquer de façon fiable cette valeur à 6dp?

Mise à jour Cela fonctionne et produit une sortie différente de ToString ("G6"):

[Fact] 
public void ParseText() 
{ 
    var numText = "51.580133"; 
    double.Parse(numText) 
     .ToString("G8") 
     .Should().Be(numText); 
} 
+1

Eh bien, croyez-vous que le problème est avec l'analyse syntaxique ou la mise en forme? Gardez à l'esprit que le «double» le plus proche de 51.580133 est * exactement * 51.58013299999999645706338924355804920196533203125. –

+1

[MSDN] (https://docs.microsoft.com/en-us/dotnet/standard/base-types/standard-numeric-format-strings#the-round-trip-r-format-specifier): _ " Si la valeur est correctement analysée avec la même valeur numérique, elle est formatée à l'aide du spécificateur de format général.Si la valeur n'est pas réexpédiée avec la même valeur numérique, elle est formatée avec 17 chiffres de précision pour un double "_ –

Répondre

5

J'ai trouvé ce point intéressant de Microsoft qui pourrait expliquer la question

En Dans certains cas, les valeurs doubles formatées avec la norme numérique "R" chaîne de format ne réussissent pas à aller-retour si compilé en utilisant le /plate-forme: x64 ou/plate-forme: commutateurs anycpu et exécuter sur 64 bits sy tiges. Pour contourner ce problème, vous pouvez formater les valeurs Double en utilisant la chaîne de format numérique standard "G17". L'exemple suivant utilise la chaîne de format "R" avec une valeur Double qui ne retourne pas avec succès, et utilise également la chaîne de format "G17" pour réussir la valeur d'origine de .

Le commentaire et un exemple se trouve ici: https://msdn.microsoft.com/en-us/library/kfsatb94(v=vs.110).aspx

+1

Wow ... c'est un bug assez horrible :( –