2009-09-04 7 views
2

J'ai un problème avec une requête que j'ai écrite où, pour une raison quelconque, la variable que j'utilise pour stocker une valeur décimale retourne 6 valeurs après la décimale (elles sont pour la plupart 0).LINQ to SQL Math.Round Problème

J'ai essayé ce qui suit (et différentes combinaisons en utilisant Math.Round) sans aucune chance.

Sales = 
      (from invhed in INVHEAD 
      ... // Joins here 
      orderby cust.State ascending 
      select new Sale 
      { 
       InvoiceLine = inv.InvoiceLine, 
       InvoiceNum = inv.InvoiceNum, 
       ... 
       NetPrice = Math.Round((inv.ExtPrice - inv.Discount) * (Decimal) (qsales.RepSplit/100.0), 2, MidpointRounding.ToEven), 
      }).ToList<Sale>(); 

Le membre NetPrice a des valeurs comme 300,000000, 5000,500000, 3245,250000, etc.

Des indices? Je n'arrive pas à trouver quoi que ce soit sur cette question en ligne.

EDIT:

Decimal.Round a fait le tour (j'ai oublié de mentionner que le membre NetPrice était un type décimal). Voir ma réponse ci-dessous.

Répondre

0

Je l'ai eu pour travailler en utilisant Decimal.Round() avec les mêmes arguments qu'avant. :)

On dirait que le problème est quelque peu sur la piste de ce que Pavel disait, où les types décimaux se comportent différemment et il semblerait que Math.Round ne fonctionne pas tout à fait comme on le ...

Merci pour toutes les informations.

2

Les zéros de fin peuvent apparaître dans la sortie de .ToString sur le type décimal. Vous devez spécifier le nombre de chiffres après le point décimal que vous voulez afficher en utilisant la bonne chaîne de format. Par exemple: -

var s = dec.ToString("#.00"); 

afficher 2 décimales.

En interne, le type décimal utilise un nombre entier et un facteur d'échelle décimal. C'est le facteur de mise à l'échelle qui donne le 0. Si vous commencez avec un type décimal avec un facteur d'échelle de 2, vous obtiendrez 2 chiffres après la virgule, même s'ils sont 0.

Ajouter et soustraire des nombres décimaux se traduira par une décimale qui a un facteur d'échelle de la est le maximum des décimales impliquées. Donc, en soustrayant une décimale avec un facteur de mise à l'échelle de 2 d'une autre avec la même décimale résultante a également un facteur de 2.

La multiplication et la division des décimales produira une décimale qui a un facteur d'échelle qui est la somme des valeurs décimales. facteurs d'échelle des deux opérandes décimaux. Avec un décimaux en multipliant le facteur d'échelle de 2 résultats dans une nouvelle décimale qui a un facteur d'échelle de 4.

Essayez ceci: -

var x = new decimal(1.01) - (decimal)0.01; 
var y = new decimal(2.02) - (decimal)0.02; 
Console.WriteLine(x * y * x * x); 

Vous obtenez 2,00000000.

+0

Ce qui est étrange, c'est que c'est l'opération de division qui gâche les choses. Si je fais juste: inv.ExtPrice - inv.Discount, je récupère une valeur décimale avec seulement 2 décimales dans ma sortie XML. – Overhed

2

System.Decimal préserve les zéros finaux de par leur conception. En d'autres termes, 1m et 1.00m sont deux decimal s différents (bien qu'ils se comparent comme égaux), et peuvent être interprétés comme étant arrondis à un nombre différent de décimales - par ex. Math.Round(1.001m) donnera 1m, et Math.Round(1.001m, 2) donnera 1.00m. Les opérateurs arithmétiques les traitent différemment - + et - produira un résultat ayant le même nombre de places que l'opérande qui en a la plupart (donc 1.50m + 0.5m == 1.10m), et * et / auront la somme du nombre de places pour leurs opérandes (donc 1.00m * 1.000m == 1.00000m).