Ho alcuni campi restituiti da una raccolta come
2.4200 2.0044 2.0000
Voglio risultati come
2.42 2.0044 2
Ho provato con String.Format
, ma restituisce 2.0000
e impostandolo su N0
arrotonda anche gli altri valori.
Non è così semplice, se l’input è una stringa? Puoi usare uno di questi:
string.Format("{0:G29}", decimal.Parse("2.0044")) decimal.Parse("2.0044").ToString("G29") 2.0m.ToString("G29")
Questo dovrebbe funzionare per tutti gli input.
Aggiornamento Dai un’occhiata ai formati numerici standard Ho dovuto impostare esplicitamente lo specificatore di precisione su 29 come affermano chiaramente i documenti:
Tuttavia, se il numero è un decimale e l’identificatore di precisione è omesso, la notazione a virgola fissa viene sempre utilizzata e gli zeri finali vengono conservati
Aggiornamento Konrad ha sottolineato nei commenti:
Attenzione per valori come 0.000001. Il formato G29 li presenterà nel modo più breve ansible, quindi passerà alla notazione esponenziale.
string.Format("{0:G29}", decimal.Parse("0.00000001",System.Globalization.CultureInfo.GetCultureInfo("en-US")))
darà “1E-08” come risultato.
Mi sono imbattuto nello stesso problema ma in un caso in cui non ho il controllo dell’output su stringa, che è stato gestito da una libreria. Dopo aver esaminato i dettagli nell’implementazione del tipo Decimal (vedere http://msdn.microsoft.com/en-us/library/system.decimal.getbits.aspx ), ho trovato un trucco accurato (qui come estensione metodo):
public static decimal Normalize(this decimal value) { return value/1.000000000000000000000000000000000m; }
La parte esponenziale del decimale viene ridotta a ciò che è necessario. Chiamando ToString () sul decimale in uscita verrà scritto il numero senza alcun valore negativo 0. Es
1.200m.Normalize().ToString();
Secondo me è più sicuro usare stringhe di formato numerico personalizzato .
decimal d = 0.00000000000010000000000m; string custom = d.ToString("0.#########################"); // gives: 0,0000000000001 string general = d.ToString("G29"); // gives: 1E-13
Uso questo codice per evitare la notazione scientifica “G29”:
public static string DecimalToString(decimal dec) { string strdec = dec.ToString(CultureInfo.InvariantCulture); return strdec.Contains(".") ? strdec.TrimEnd('0').TrimEnd('.') : strdec; }
Ho trovato una soluzione elegante da http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/
Fondamentalmente
decimale v = 2,4200 M;
v.ToString ( “# ######”.); // restituirà 2.42. Il numero di # è il numero di cifre decimali supportate.
Usa il simbolo cancelletto ( #
) per visualizzare solo gli zero finali quando necessario. Guarda i test qui sotto.
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%
Questo fa esattamente quello che vuoi:
Se il tuo valore iniziale è decimal
:
decimal source = 2.4200m; string output = ((double)source).ToString();
Se il tuo valore iniziale è una string
:
string source = "2.4200"; string output = double.Parse(source).ToString();
E dovrebbe costare prestazioni minime.
Dipende da cosa rappresenta il tuo numero e da come vuoi gestire i valori: è una valuta, hai bisogno di arrotondare o troncare, hai bisogno di questo arrotondamento solo per la visualizzazione?
Se per la visualizzazione prendere in considerazione la formattazione i numeri sono x.ToString (“”)
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx e
http://msdn.microsoft.com/en-us/library/0c899ak8.aspx
Se si tratta solo di arrotondare, utilizzare il sovraccarico Math.Round che richiede un sovraccarico MidPointRounding
http://msdn.microsoft.com/en-us/library/ms131274.aspx )
Se ottieni un valore da un database, considera il cast invece della conversione: double value = (decimale) myRecord [“columnName”];
Un approccio di livello molto basso, ma credo che questo sarebbe il modo più performante usando solo i calcoli integer veloci (e nessun analisi lenta delle stringhe e metodi sensibili alla cultura):
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); }
La risposta molto semplice è usare TrimEnd (). Ecco il risultato,
double value = 1.00; string output = value.ToString().TrimEnd('0');
L’output è 1 Se il mio valore è 1,01, il mio output sarà 1,01
Il seguente codice potrebbe essere utilizzato per non utilizzare il tipo di stringa:
int decimalResult = 789.500 while (decimalResult>0 && decimalResult % 10 == 0) { decimalResult = decimalResult / 10; } return decimalResult;
Restituisce 789,5
Puoi semplicemente impostare come:
decimal decNumber = 23.45600000m; Console.WriteLine(decNumber.ToString("0.##"));
Tronca gli zeri finali è molto semplice, risolvibile con un cast duplex:
decimal mydecimal = decimal.Parse("1,45000000"); //(I) decimal truncate = (decimal)(double)mydecimal; //(II)
(I) -> Analizza il valore decimale da qualsiasi origine stringa.
(II) -> Primo: Cast per raddoppiare rimuovere gli zero finali. Secondo: altro cast al decimale perché non esiste una conversione implicita da decimale a doppio e viceversa)
prova questo codice:
string value = "100"; value = value.Contains(".") ? value.TrimStart('0').TrimEnd('0').TrimEnd('.') : value.TrimStart('0');
prova così
string s = "2.4200"; s = s.TrimStart('0').TrimEnd('0', '.');
e poi convertirlo in float