2013-05-15 18 views
14

Si verifica un problema quando si tenta di convertire decimal? in string. Scenario èProblema di conversione Decimal ToString() in C#

decimal decimalValue = .1211; 
string value = (decimalValue * 100).ToString(); 

Risultato corrente: value = 12,1100

Risultato atteso: value = 12.11

prega fatemelo sapere, quello che potrebbe essere motivo per questo.

+1

Il motivo è probabilmente il formato numerico predefinito del sistema per i numeri decimali. –

+2

Volevi che visualizzasse più di due cifre decimali se non sono zero? Cioè, se tu avessi '.12113405' vorresti che appaia come' 12.113405'? –

+0

Proprio quello che stavo pensando: sono solo gli zeri finali, o vuoi sempre limitare di 2 decimali? Nel primo caso, nessuna delle risposte fornisce una buona risposta. –

risposta

16

Decimal conserva gli zero finali nel un numero Decimal.Se si desidera che due cifre decimali invece:

decimal? decimalValue = .1211m; 
string value = ((decimal)(decimalValue * 100)).ToString("#.##") 

http://msdn.microsoft.com/en-us/library/0c899ak8.aspx

o

string value = ((decimal)(decimalValue * 100)).ToString("N2") 

http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx

Da System.Decimal:

Una deci numero mal è un valore a virgola mobile che consiste di un segno, un valore numerico dove ogni cifra del valore varia da 0 a 9, e un fattore di scala che indica la posizione di un punto decimale fluttuante che separa l'integrale e le parti frazionali del valore numerico.

La rappresentazione binaria di un valore decimale rappresentato da un segno 1 bit, un numero intero 96 bit, e una scala fattore utilizzato per dividere il 96 bit intero e specificare quale parte di esso è una frazione decimale. La scala fattore è implicitamente il numero 10, elevato a un esponente compreso tra 0 a 28. Pertanto, il binario rappresentazione di un valore decimale è della forma, ((-2 a 2 )/10 (0 a 28)), dove -2 -1 è uguale a MinValue e 2 -1 è uguale a MaxValue.

Il fattore di ridimensionamento preserva anche gli zero finali in un numero decimale. Gli zeri finali non influiscono sul valore di un numero decimale nelle operazioni aritmetiche o di confronto . Tuttavia, gli zero finali possono essere rilevati dal metodo ToString se viene applicata una stringa di formato appropriata < <.

Osservazione:

  1. la moltiplicazione decimale deve essere colato a decimale, perché Nullable<decimal>.ToString non ha provider di formato
  2. come Chris ha sottolineato il necessario per gestire il caso che il Nullable<decimal> è null.Un modo è usare il Null-Coalescing-Operator:

    ((decimal)(decimalValue ?? 0 * 100)).ToString("N2") 
    

Questo articolo da Jon Skeet è la pena di leggere:

Decimal floating point in .NET (seach per mantenendo zeri se siete impazienti)

+0

La conversione in 'decimale' genererà un' InvalidOperationException' con questo codice, mentre il codice originale di Pushkar risulterebbe in una stringa vuota. Forse non pertinente in questo caso però. –

+0

Scusa Tim, volevo dire che verrà lanciato quando 'decimalValue' è' null'. –

+0

@ChrisSinclair: Grazie, aggiunto un commento. –

6

Poiché l'utilizzo di Nullable<T> come metodo decimal, Nullable<T>.ToString() non ha sovraccarico, accetta parametri che è possibile utilizzare per la formattazione.

Invece di, è possibile trasmettere espressamente a decimal ed è possibile utilizzare il metodo .ToString() per la formattazione.

Basta usare il formato "0.00" nel metodo .ToString().

decimal? decimalValue = .1211M; 
string value = ((decimal)(decimalValue * 100)).ToString("0.00"); 
Console.WriteLine(value); 

Uscita sarà;

12.11 

Questo è un DEMO.

In alternativa, è possibile utilizzare Nullable<T>.Value senza alcuna conversazione simile;

string value = (decimalValue * 100).Value.ToString("0.00"); 

Partenza per maggiori informazioni da Custom Numeric Format Strings

+0

La conversione in 'decimale' genererà un' InvalidOperationException' con questo codice, mentre il codice originale di Pushkar risulterebbe in una stringa vuota. Forse non pertinente in questo caso però. –

+0

@ChrisSinclair No, non genererà alcuna eccezione in questo caso. –

+0

Esegue quando eseguo il codice letteralmente in LinqPad. EDIT: Spara scusa, intendevo quando 'decimalValue' è' null'. Scusa, mi sono dimenticato di scrivere _write_ effettivamente. –

0
String.Format("{0:0.00}", decimalValue * 100); 

È possibile utilizzare .Format() come alternativa al .ToString("0.00").

2

In alternativa, è possibile specificare il formato "F2", ad esempio: string val = decVal.ToString("F2") in quanto specifica 2 posizioni decimali.

2

Utilizzare fixed-point ("F) format specifier.

string value = (decimalValue * 100).ToString("F"); 

L'identificatore di precisione di default si basa sul valore di NumberFormatInfo.NumberDecimalDigits di proprietà che di default ha valore 2. Quindi, se non specificare una cifra aftyer "F", di default specifica due cifre decimali.

F0 - No decimal places 
F1 - One decimal place 
0

Dal decimal? non ha un sovraccarico ToString(string format), il modo più semplice è utilizzare invece String.Format che fornirà risultati coerenti con lo null caso per decimalValue così (con conseguente una stringa vuota) rispetto al codice originale:

string value = String.Format("{0:#.##}", decimalValue * 100); 

Ma ci sono alcune altre considerazioni per altri numeri che non erano chiare su.

Se si dispone di un numero che non produce un valore maggiore di 0, mostra uno zero iniziale? Cioè, per 0.001211, viene visualizzato come 0.12 o .12? Se si desidera che lo zero, utilizzare questo invece (notare il cambiamento #.##-0.##):

string value = String.Format("{0:0.##}", decimalValue * 100); 

Se si dispone di più di 2 cifre decimali significativi, vuoi quelli visualizzati? Quindi se avessi .12113405 verrà visualizzato come 12.113405? Se in modo da utilizzare:

string value = String.Format("{0:#.############}", decimalValue * 100); 

(Onestamente, penso che ci deve essere una stringa meglio formattazione di questo, soprattutto in quanto supporta solo 12 cifre decimali)

E, naturalmente, se si desidera che entrambi gli zeri iniziali e più cifre decimali, basta combinare i due di cui sopra:

string value = String.Format("{0:0.############}", decimalValue * 100); 
0

Nel caso in cui non si vuole limitare a una certa quantità di cifre decimali:

decimal? decimalValue = .1211; 
string value = decimalValue == null 
       ? "0" 
       : decimalValue == 0 
       ? "0" 
       : (decimalValue * 100).ToString().TrimEnd('0'); 

Questo riduce qualsiasi (se presente) zero finale della stringa e restituisce anche "0" se decimalValue è nullo. Se il valore è 0, viene restituito "0" senza ritaglio.