2010-04-09 2 views
1

quelqu'un peut-il expliquer pourquoi j'obtiens les résultats suivants?System.Deconds arrondis sur l'affectation

Dim badDecimal As Decimal = 54.50327999999999 
Dim expectedDecimal As Decimal = CDec("54.50327999999999") 

badDecimal = 54.50328D, tandis que expectedDecimal = 54.50327999999999D. Ma compréhension est que badDecimal devrait contenir la valeur de expectedDecimal (le fait que expectedDecimal puisse contenir la valeur correcte suggère que le type Decimal a la précision pour contenir la valeur).

merci d'avance pour toute aide donnée.

+1

Je ne sais pas tout ce que beaucoup VB.NET, mais en C# vous devez suffixe un numéro avec le caractère M pour indiquer qu'il est un nombre décimal, sinon c'est un double. Donc, avez-vous besoin de faire la même chose dans VB, de sorte qu'en fait, la première ligne assigne une valeur double (la double interprétation de 54.50327999999999) à une décimale, perdant ainsi la précision à la compilation? –

+0

vous bel homme, c'était effectivement le problème! J'ai supposé que j'étais en train de déclarer que la variable var était de type décimal, le compilateur déduirait cela. Voulez-vous re-poster cette réponse afin que je puisse la marquer comme la solution? – WiseGuyEh

+0

Commentaire repensé comme réponse ici: http://stackoverflow.com/questions/2606610/system-decimal-rounds-on-assignment/2606685#2606685 –

Répondre

6

Selon cette page: Decimal Data Type (Visual Basic), vous devez suffixe valeurs littérales décimales avec le caractère majuscule D, sinon le compilateur va essayer de le compiler comme approprié, mais différent, type numérique, comme Integer, Long, Double, etc. en fonction de la valeur constante utilisée.

Dans votre cas, le code semble essentiellement comme au compilateur:

Dim badDecimal As Decimal = (constant of type System.Double) 

Et donc déjà à la compilation, la valeur constante a perdu sa précision.

changer simplement le code à ceci:

Dim badDecimal As Decimal = 54.50327999999999D 
              ^
              +-- add this 

et il devrait fonctionner comme prévu.

Cependant, je serais fatigué d'attendre les deux variables à comparer identiques, il y a assez de questions sur StackOverflow sur les "problèmes" avec les types virgule flottante pour au moins me faire savoir que vous pourriez avoir une différence mineure dans la Nième décimale , assez petit pour ne pas arriver à l'affichage ou au débogueur, mais assez pour que les deux variables soient différentes. Donc, gardez cela à l'esprit si vous avez l'intention de les comparer, la manière typique est de soustraire une valeur de l'autre, prenez sa valeur absolue, et comparez cela avec une valeur minuscule pour dire "J'accepte un autre gros, mais pas plus grand ".

ie. comme ceci:

If Math.Abs(badDecimal - expectedDecimal) < 0.000001 Then 

au lieu de ceci:

If badDecimal = expectedDecimal Then 
+0

Mes excuses à l'avance si la déclaration "If Math.Abs ​​..." doesn 't compiler hors de la boîte, comme je l'ai dit dans mon commentaire original, je ne suis pas tout à courant dans VB.NET :) –

+0

Je ne suis pas sûr que 'decimal' compte comme un type à virgule flottante pour le virgule flottante habituelle! = problèmes de nombre réel. (Mais vous avez raison avec le problème ici: assigner un double à une décimale provoque l'arrondi. – Richard

+0

qui devrait compiler très bien, merci pour le conseil – WiseGuyEh