Ich habe einige Felder von einer Sammlung als zurückgegeben
2.4200
2.0044
2.0000
Ich möchte Ergebnisse wie
2.42
2.0044
2
Ich habe es mit String.Format
versucht, aber es gibt 2.0000
zurück und setzt N0
, wobei die anderen Werte ebenfalls gerundet werden.
Ist es nicht so einfach, wenn die Eingabe IS eine Zeichenfolge ist? Sie können eine davon verwenden:
string.Format("{0:G29}", decimal.Parse("2.0044"))
decimal.Parse("2.0044").ToString("G29")
2.0m.ToString("G29")
Dies sollte für alle Eingaben funktionieren.
Update Schauen Sie sich die Standard Numeric Formats an Ich musste den Präzisionsspezifizierer explizit auf 29 setzen, da die Dokumente eindeutig angeben:
Wenn es sich bei der Zahl jedoch um eine Dezimalzahl handelt und der Genauigkeitsbezeichner weggelassen wird, wird immer die Festkommennotation verwendet und nachfolgende Nullen werden beibehalten
UpdateKonradwies darauf hin in den Kommentaren:
Achten Sie auf Werte wie 0,000001. Im G29-Format werden sie so kurz wie möglich dargestellt, sodass auf die Exponentialnotation umgeschaltet wird.
string.Format("{0:G29}", decimal.Parse("0.00000001",System.Globalization.CultureInfo.GetCultureInfo("en-US")))
gibt als Ergebnis "1E-08" aus.
Ich bin auf dasselbe Problem gestoßen, aber in einem Fall, in dem ich keine Kontrolle über die Ausgabe von String habe, die von einer Bibliothek erledigt wurde. Nachdem ich die Details des Decimal-Typs (siehe http://msdn.Microsoft.com/de-de/library/system.decimal.getbits.aspx ) genauer betrachtet habe, habe ich netter Trick (hier als Erweiterungsmethode):
public static decimal Normalize(this decimal value)
{
return value/1.000000000000000000000000000000000m;
}
Der Exponententeil der Dezimalzahl wird auf das Notwendige reduziert. Beim Aufruf von ToString () für die Ausgabe-Dezimalzahl wird die Zahl ohne nachstehende 0 geschrieben.
1.200m.Normalize().ToString();
Meiner Meinung nach ist es sicherer, Custom Numeric Format Strings zu verwenden.
decimal d = 0.00000000000010000000000m;
string custom = d.ToString("0.#########################");
// gives: 0,0000000000001
string general = d.ToString("G29");
// gives: 1E-13
Ich verwende diesen Code, um die wissenschaftliche Notation "G29" zu vermeiden:
public static string DecimalToString(decimal dec)
{
string strdec = dec.ToString(CultureInfo.InvariantCulture);
return strdec.Contains(".") ? strdec.TrimEnd('0').TrimEnd('.') : strdec;
}
Verwenden Sie das Hash-Symbol (#
), um bei Bedarf nur nachlaufende 0 anzuzeigen. Siehe die Tests unten.
decimal num1 = 13.1534545765;
decimal num2 = 49.100145;
decimal num3 = 30.000235;
num1.ToString("0.##"); //13.15%
num2.ToString("0.##"); //49.1%
num3.ToString("0.##"); //30%
Ich fand eine elegante Lösung von http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/
Grundsätzlich gilt
dezimalzahl v = 2,4200 M;
v.ToString ("#. ######"); // Gibt 2.42 zurück. Die Anzahl von # gibt an, wie viele Dezimalstellen Sie unterstützen.
Das wird funktionieren:
decimal source = 2.4200m;
string output = ((double)source).ToString();
Oder wenn Ihr Ausgangswert string
ist:
string source = "2.4200";
string output = double.Parse(source).ToString();
Achten Sie auf diesen Kommentar .
Eine sehr untergeordnete Herangehensweise, aber ich glaube, dies wäre der performanteste Weg, wenn nur schnelle Ganzzahlberechnungen (und keine langsamen Zeichenfolgenanalyse und kultursensitive Methoden) verwendet werden:
public static decimal Normalize(this decimal d)
{
int[] bits = decimal.GetBits(d);
int sign = bits[3] & (1 << 31);
int exp = (bits[3] >> 16) & 0x1f;
uint a = (uint)bits[2]; // Top bits
uint b = (uint)bits[1]; // Middle bits
uint c = (uint)bits[0]; // Bottom bits
while (exp > 0 && ((a % 5) * 6 + (b % 5) * 6 + c) % 10 == 0)
{
uint r;
a = DivideBy10((uint)0, a, out r);
b = DivideBy10(r, b, out r);
c = DivideBy10(r, c, out r);
exp--;
}
bits[0] = (int)c;
bits[1] = (int)b;
bits[2] = (int)a;
bits[3] = (exp << 16) | sign;
return new decimal(bits);
}
private static uint DivideBy10(uint highBits, uint lowBits, out uint remainder)
{
ulong total = highBits;
total <<= 32;
total = total | (ulong)lowBits;
remainder = (uint)(total % 10L);
return (uint)(total / 10L);
}
Hängt davon ab, was Ihre Zahl darstellt und wie Sie die Werte verwalten möchten: Ist dies eine Währung? Brauchen Sie eine Rundung oder eine Kürzung? Brauchen Sie diese Rundung nur zur Anzeige?
Wenn für die Anzeige Formatierungen in Betracht gezogen werden sollen, sind x.ToString ("")
http://msdn.Microsoft.com/de-de/library/dwhawy9k.aspx und
http://msdn.Microsoft.com/de-de/library/0c899ak8.aspx
Wenn es nur rund ist, verwenden Sie eine Math.Round-Überladung, die eine MidPointRounding-Überladung erfordert.
http://msdn.Microsoft.com/de-de/library/ms131274.aspx )
Wenn Sie Ihren Wert aus einer Datenbank erhalten, sollten Sie die Umwandlung anstelle der Konvertierung in Betracht ziehen: Double value = (dezimal) myRecord ["columnName"];
Wenn Sie die Dezimalzahl beibehalten möchten, versuchen Sie folgendes Beispiel:
number = Math.Floor(number * 100000000) / 100000000;
Eine sehr einfache Antwort ist TrimEnd () zu verwenden. Hier ist das Ergebnis
double value = 1.00;
string output = value.ToString().TrimEnd('0');
Die Ausgabe ist 1 ... Wenn mein Wert 1,01 ist, ist meine Ausgabe 1,01
Das ist ganz einfach.
decimal decNumber = Convert.ToDecimal(value);
return decNumber.ToString("0.####");
Geprüft.
Prost :)