2013-07-14 15 views
6

Ich muss eine Zahl auf 2 Dezimalstellen abschneiden, was im Grunde bedeutet Abschneiden der zusätzlichen Ziffern.Eine Zahl auf angegebene Dezimalstellen abschneiden

ZB:

2.919  ->  2.91 

2.91111 ->  2.91 

Warum? Dies ist, was SQL Server tut, wenn eine bestimmte Genauigkeit von gespeichert wird. Wenn z. B. eine Spalte Dezimal (8,2) ist und Sie versuchen, eine Zahl von 9.1234 einzufügen/zu aktualisieren, werden die 3 und 4 abgeschnitten.

Ich muss genau dasselbe in C# -Code tun.

Die einzigen Möglichkeiten, dass ich es zu tun, sind entweder denken kann:

  1. Mit dem stringformatter zu „drucken“ es nur zwei Dezimalstellen, und dann in eine Dezimalzahl umzuwandeln, zB :

    decimal tooManyDigits = 2.1345 
    
    decimal ShorterDigits = Convert.ToDecimal(tooManyDigits.ToString("0.##")); 
    
    // ShorterDigits is now 2.13 
    

    ich damit nicht zufrieden bin, weil es eine zu-String und dann eine andere Zeichenfolge dezimal Umwandlung, die ein bisschen verrückt scheint sich bringt.

  2. Mit Math.Truncate (die nur eine ganze Zahl annimmt), so ich es mit 100 multiplizieren können, kürzen sie, dann teilen mit 100. Beispiel:

    decimal tooLongDecimal = 2.1235; 
    
    tooLongDecimal = Math.Truncate(tooLongDecimal * 100)/100; 
    

    Ich bin auch nicht glücklich mit dies, weil wenn ichLongDecimal ist 0, Ich bekomme eine Division durch 0 Fehler.

Sicherlich gibt es einen besseren + einfacheren Weg! Irgendwelche Vorschläge?

+2

'0/100' von 0 Fehler nicht eine Kluft. Es ist "0", was Sie erwarten würden. – xbonez

+0

(0 * 100)/100 = 0 –

+0

@sehe truncate! = Rund –

Antwort

5

Sie haben die Frage selbst beantwortet. es scheint, du hast nur missverstanden, was Division durch Null bedeutet. Der richtige Weg, dies zu tun ist, sich zu vermehren, gestutzt, dann devide, wie folgt aus:

decimal TruncateTo100ths(decimal d) 
{ 
    return Math.Truncate(d* 100)/100; 
} 

TruncateTo100ths(0m);  // 0 
TruncateTo100ths(2.919m); // 2.91 
TruncateTo100ths(2.91111m); // 2.91 
TruncateTo100ths(2.1345m); // 2.13 

Es gibt keine Division durch Null hier gibt es nur eine Division durch 100, das absolut sicher ist.

+0

dam du schlägst mich :) war gerade das gleiche math.truncate Beispiel lol +1 schreiben. – terrybozzio

0

Mit decimal.ToString('0.##')auch erlegt Runden:

1.119M.ToString("0.##") // -> 1.12 

(. Ja, wahrscheinlich ein Kommentar sein sollte, aber es ist schwer, auch als solche zu formatieren)

1

ich mit p.s.w.g. einverstanden Ich hatte die ähnliche Anforderung und hier ist meine Erfahrung und eine allgemeinere Funktion zum Abschneiden.

http://snathani.blogspot.com/2014/05/truncating-number-to-specificnumber-of.html

public static decimal Truncate(decimal value, int decimals) 
{ 
    decimal factor = (decimal)Math.Pow(10, decimals); 
    decimal result = Math.Truncate(factor * value)/factor; 
    return result; 
} 
3

Die bisher angebotenen mathematischen Lösungen sind anfällig mit großen Zahlen und/oder eine große Anzahl von Dezimalstellen überzulaufen.Betrachten Sie stattdessen die folgende Erweiterung:

[System.Runtime.CompilerServices.Extension()] 
public static decimal TruncateDecimal(decimal d, int decimals) 
{ 
    if (decimals < 0) 
     throw new ArgumentOutOfRangeException("decimals", "Value must be in range 0-28."); 
    else if (decimals > 28) 
     throw new ArgumentOutOfRangeException("decimals", "Value must be in range 0-28."); 
    else if (decimals = 0) 
     return Math.Truncate(d); 
    else { 
     decimal integerPart = Math.Truncate(d); 
     decimal scalingFactor = d - integerPart; 
     decimal multiplier = Math.Pow(10, decimals); 

     scalingFactor = Math.Truncate(scalingFactor * multiplier)/multiplier; 

     return integerPart + scalingFactor; 
    } 
} 

Verbrauch:

decimal value = 18446744073709551615.262626263m; 
value = value.TruncateDecimal(6); 
Verwandte Themen