2010-03-16 41 views
112

Come si formatta un Double in un String in C# in modo da avere solo due cifre decimali?C# Double - ToString() formattazione con due cifre decimali ma senza arrotondamento

Se utilizzo String.Format("{0:0.00}%", myDoubleValue), il numero è arrotondato e desidero un semplice troncamento senza arrotondamenti. Voglio anche che la conversione a String sia sensibile alla cultura.

+0

Che cosa si intende per " sensibile alla cultura "? Ciò significa che l'esito della formattazione deve variare in base al valore culturale fornito dal programmatore? O vuoi usare qualunque cultura è l'impostazione predefinita per il thread corrente? – CesarGon

risposta

152

Io uso il seguente:

double x = Math.Truncate(myDoubleValue * 100)/100; 

Per esempio:

Se il numero è 50,947,563 mila e si utilizza il seguente, il seguente accadrà:

- Math.Truncate(50.947563 * 100)/100; 
- Math.Truncate(5094.7563)/100; 
- 5094/100 
- 50.94 

E c'è la vostra risposta troncato, ora per formattare la stringa è sufficiente fare quanto segue:

string s = string.Format("{0:N2}%", x); // No fear of rounding and takes the default number format 
+2

-1 È possibile eseguire la formattazione sensibile alla cultura nello stesso passo 'string.Format' che formatta la stringa. Vedi la mia risposta qui sotto. – CesarGon

+0

Precisamente: il poster richiede una soluzione che includa la formattazione sensibile alla cultura. La tua risposta è perfettamente OK nella parte troncante, ma, come sottolinei, "il cambiamento della cultura dovrebbe essere fatto separatamente". Non specifichi come farlo, quindi penso che la tua risposta risponda solo parzialmente alla domanda. – CesarGon

+2

OK, nessun problema, inserirò semplicemente un addendum. –

30

ti suggerisco di troncare prima, e poi formato:

double a = 123.4567; 
double aTruncated = Math.Truncate(a * 100)/100; 
CultureInfo ci = new CultureInfo("de-DE"); 
string s = string.Format(ci, "{0:0.00}%", aTruncated); 

utilizzare la costante 100 per 2 cifre troncare; usa un 1 seguito da altrettanti zeri come cifre dopo il punto decimale che desideri. Usa il nome della cultura di cui hai bisogno per regolare il risultato della formattazione.

0

Si potrebbe anche scrivere il proprio IFormatProvider, anche se suppongo che alla fine si dovrebbe pensare a un modo per eseguire il troncamento effettivo.

.NET Framework supporta anche la formattazione personalizzata. Questo in genere comporta la creazione di una classe di formattazione che implementa sia IFormatProvider che ICustomFormatter. (msdn)

Almeno sarebbe facilmente riutilizzabile.

C'è un articolo su come implementare il proprio IFormatProvider/ICustomFormatter here at CodeProject. In questo caso, "estendere" un formato numerico esistente potrebbe essere la soluzione migliore. Non sembra troppo difficile.

5

Questo è il lavoro per me

string prouctPrice = Convert.ToDecimal(String.Format("{0:0.00}", Convert.ToDecimal(yourString))).ToString(); 
5

la funzione C#, come espresso da Kyle Rozendo:

string DecimalPlaceNoRounding(double d, int decimalPlaces = 2) 
{ 
    d = d * Math.Pow(10, decimalPlaces); 
    d = Math.Truncate(d); 
    d = d/Math.Pow(10, decimalPlaces); 
    return string.Format("{0:N" + Math.Abs(decimalPlaces) + "}", d); 
} 
64
decimal d = 0.241534545765m; 
decimal d2 = 0.241m; 
decimal d3 = 0.2m; 

d.ToString("0.##%");  //24.15% 
d2.ToString("0.##%");  //24.1% 
d3.ToString("0.##%");  //20% 

http://dobrzanski.net/2009/05/14/c-decimaltostring-and-how-to-get-rid-of-trailing-zeros/

+7

Questo non funziona. Provalo con 0.2415999. Questa soluzione arrotonda, non tronca. – BJury

+2

Wow, così tanti voti eppure sta usando l'arrotondamento. Potrebbe essere necessario sottolineare che l'arrotondamento si sta dirigendo verso la cifra decimale più vicina richiesta, mentre il troncamento si interrompe dopo il decimale più vicino richiesto. – mysticcoder

+0

@mysticcoder Immagino che la mia risposta ottenga così tanti voti perché arrivano alla domanda delle ops in una ricerca su Google nello stesso modo in cui ho fatto, cercando di rimuovere gli zero finali e non cercando il desiderio di arrotondamento della domanda delle operazioni. Credo che dovrei cancellare la mia risposta ... –

2

So che questo è un filo vecchio, ma io Ho appena dovuto farlo. Mentre gli altri approcci qui funzionano, volevo un modo semplice per essere in grado di influenzare molte chiamate a string.format. Quindi aggiungere lo Math.Truncate a tutte le chiamate non era una buona opzione. Inoltre, poiché parte della formattazione è memorizzata in un database, lo ha reso ancora peggiore.

Così, ho fatto un provider personalizzato formato che mi permettesse di aggiungere troncamento per la stringa di formattazione, ad esempio:

string.format(new FormatProvider(), "{0:T}", 1.1299); // 1.12 
string.format(new FormatProvider(), "{0:T(3)", 1.12399); // 1.123 
string.format(new FormatProvider(), "{0:T(1)0,000.0", 1000.9999); // 1,000.9 

L'implementazione è piuttosto semplice ed è facilmente estensibile ad altri requisiti.

public class FormatProvider : IFormatProvider, ICustomFormatter 
{ 
    public object GetFormat(Type formatType) 
    { 
     if (formatType == typeof (ICustomFormatter)) 
     { 
      return this; 
     } 
     return null; 
    } 

    public string Format(string format, object arg, IFormatProvider formatProvider) 
    { 
     if (arg == null || arg.GetType() != typeof (double)) 
     { 
      try 
      { 
       return HandleOtherFormats(format, arg); 
      } 
      catch (FormatException e) 
      { 
       throw new FormatException(string.Format("The format of '{0}' is invalid.", format)); 
      } 
     } 

     if (format.StartsWith("T")) 
     { 
      int dp = 2; 
      int idx = 1; 
      if (format.Length > 1) 
      { 
       if (format[1] == '(') 
       { 
        int closeIdx = format.IndexOf(')'); 
        if (closeIdx > 0) 
        { 
         if (int.TryParse(format.Substring(2, closeIdx - 2), out dp)) 
         { 
          idx = closeIdx + 1; 
         } 
        } 
        else 
        { 
         throw new FormatException(string.Format("The format of '{0}' is invalid.", format)); 
        } 
       } 
      } 
      double mult = Math.Pow(10, dp); 
      arg = Math.Truncate((double)arg * mult)/mult; 
      format = format.Substring(idx); 
     } 

     try 
     { 
      return HandleOtherFormats(format, arg); 
     } 
     catch (FormatException e) 
     { 
      throw new FormatException(string.Format("The format of '{0}' is invalid.", format)); 
     } 
    } 

    private string HandleOtherFormats(string format, object arg) 
    { 
     if (arg is IFormattable) 
     { 
      return ((IFormattable) arg).ToString(format, CultureInfo.CurrentCulture); 
     } 
     return arg != null ? arg.ToString() : String.Empty; 
    } 
} 
7

i usano price.ToString("0.00") per ottenere il principale 0s

10

metodo più semplice, utilizzare stringhe di formato numerico:

double total = "43.257" 
MessageBox.Show(total.ToString("F")); 
+1

In realtà questo metodo fa girare https://msdn.microsoft.com/en-us/library/dwhawy9k(v=vs.110).aspx#FFormatString – elvin

1

segue può essere utilizzato per la visualizzazione solo che utilizza la proprietà di stringa ..

double value = 123.456789; 
String.Format("{0:0.00}", value); 
3

Come aggiungere una decima in più l che deve essere arrotondato e poi scartato:

var d = 0.241534545765; 
var result1 = d.ToString("0.###%"); 

var result2 = result1.Remove(result1.Length - 1); 
+1

È divertente come una risposta non funzionante abbia 60 voti (da oggi), e questa soluzione piuttosto semplice e a prova di proiettile ne ha solo uno .... –

+0

Questo non funzionerà nel caso in cui l'arrotondamento colpisca più di una cifra sopra il valore limite. Ad esempio 0.199999 finirà con 0.20 come codice, invece di 0.19. – Bernem

0

Per cosa vale la pena, per mostrare la valuta, è possibile utilizzare "C":

double cost = 1.99; 
m_CostText.text = cost.ToString("C"); /*C: format as currentcy */ 

uscita: $1.99

Problemi correlati