2010-03-30 5 views
15

courte et version sucrée:decimal.TryParse() gouttes leader "1"

Sur une machine sur environ est convertissaient "1,01" à 0,01


une centaine de machines de test decimal.TryParse()

D'accord, cela va sembler fou, mais supporter avec moi ...

Nous avons une application client qui communique avec un service web via JSON, et ce service renvoie une valeur décimale sous forme de chaîne de sorte que nous le stockons comme une chaîne dans notre objet modèle:

[DataMember(Name = "value")] 
public string Value { get; set; } 

Lorsque nous affichons cette valeur à l'écran, elle est formatée à un nombre spécifique de décimales. Donc, le processus que nous utilisons est une chaîne -> décimal puis décimal -> chaîne.

L'application est en cours de test final et fonctionne sur plus de 100 machines, où tout cela fonctionne très bien. Cependant sur une machine si la valeur décimale a un '1' en tête puis elle est remplacée par un zéro. J'ai ajouté l'enregistrement simple au code afin qu'il ressemble à ceci:

Log("Original string value: {0}", value); 
decimal val; 
if (decimal.TryParse(value, out val)) 
{ 
    Log("Parsed decimal value: {0}", val); 
    string output = val.ToString(format, CultureInfo.InvariantCulture.NumberFormat); 
    Log("Formatted string value: {0}", output); 
    return output; 
} 

Sur ma machine - une toute autre machine cliente - la sortie du fichier journal est:

  • valeur de chaîne d'origine: 1,010000
  • valeur décimale Parsed: 1,010000
  • valeur de chaîne formatée: 1,01

Sur la machine défectueuse la sortie est:

  • valeur de chaîne d'origine: 1,010000
  • valeur décimale Parsed: 0,010000
  • valeur de chaîne Formaté: 0,01

Il Il semblerait que la méthode decimal.TryParse soit en faute.

Les choses que nous avons essayé:

  • désinstallant et en réinstallant l'application cliente
  • désinstallant et en réinstallant .net 3.5 sp1
  • En comparant les paramètres régionaux de la machine défectueuse pour les numéros (en utilisant l'anglais (Royaume-Uni)) à ceux d'une machine de travail - pas de différences.

Est-ce que quelqu'un a déjà vu quelque chose comme ça ou a des suggestions? Je suis en cours d'exécution rapidement des idées ...


Pendant que je tapais ce encore plus d'information est venu: Le passage d'une valeur de chaîne de « 10000 » pour convertir.ToInt32() renvoie 0, de sorte que semble également laisser tomber les principaux 1.


D'autres tests basés sur les commentaires:

  • 1,01 -> 0,01
  • 111,01 -> 11,01
  • 123.01 -> 23,01
  • 231,01 -> 231,01
  • 01,01 -> 1,01

Donc il semblerait que cela affecte seulement 1s et seulement s'ils sont le premier caractère de la chaîne. Très étrange, mais au moins c'est cohérent.

+1

Bizarre. Que se passe-t-il avec d'autres chiffres comme "123" ou "321"? –

+0

Mauvaise RAM dans la machine? Avez-vous essayé d'exécuter quelque chose comme memtest86? –

+0

Ceci est une très mauvaise idée, mais si vous pré-pad avec un zéro ...? – spender

Répondre

16

Je suis capable de reproduire vos résultats. Considérez:

public NumberFormatInfo OneIsPositiveSignFormat() 
{ 
    NumberFormatInfo custom = new NumberFormatInfo(); 
    custom.PositiveSign = "1"; 
    return custom; 
} 

Et puis:

if (decimal.TryParse(value, NumberStyles.Number, OneIsPositiveSignFormat(), out val)) 

La chose est: Paramètres régionaux ne vous montre pas le signe positif courant, et surtout: vous n'avez pas défini la culture lors de l'analyse du nombre .

La valeur peut provenir de différents endroits: Il peut provenir du registre que les paramètres par défaut du système, ou les valeurs par défaut aurait pu être défini par le code:

CultureInfo customCulture = (CultureInfo)CultureInfo.InvariantCulture.Clone(); 
customCulture.NumberFormat = OneIsPositiveSignFormat(); 
Thread.CurrentThread.CurrentCulture = customCulture; 
+1

Une réponse intéressante, mais cela pose la question que si les paramètres régionaux ne vous permettent pas de définir le signe positif et que les paramètres régionaux du PO sont les mêmes que ceux des autres machines, comment le signe positif a-t-il pu être changé? Je ne suis pas en désaccord avec vous, cela correspond parfaitement aux exemples, je suis juste curieux. –

+2

Et nous avons un gagnant! Juste couru le code suivant sur sa machine: Console.WriteLine (System.Globalization.CultureInfo.CurrentCulture.NumberFormat.PositiveSign); et il sort "1". Maintenant, juste besoin de comprendre comment changer ce retour ... –

+0

Je parie que c'était un programme tiers qui a fait cela. Quelle monstruosité. – Kugel

-1

Pour voir comment les paramètres régionaux sont définis pour cet ordinateur, il se peut que "." est défini comme séparateur de milliers pas comme séparateur décimal. Essayez d'utiliser Decimal.TryParse (String, NumberStyles, IFormatProvider, out Decimal val) et passez NumberFormatInfo créé avec le séparateur décimal "."

+2

OP a déjà dit qu'il n'y a pas de différences dans les paramètres régionaux - plus si 1.000 a été entré lorsque '.' était un séparateur de milliers, il donnerait 1000, pas 0. –

Questions connexes