Come arrotondare un valore decimale a 2 decimali (per l'output su una pagina)
Domanda
Quando si visualizza il valore di un decimale attualmente con .ToString ()
, è preciso come 15 decimali e, poiché lo sto usando per rappresentare dollari e centesimi, voglio solo l'output essere di 2 decimali.
Per questo uso una variante di .ToString ()
?
Soluzione
decimalVar.ToString ("#.##"); // returns "" when decimalVar == 0
o
decimalVar.ToString ("0.##"); // returns "0" when decimalVar == 0
Altri suggerimenti
So che questa è una vecchia domanda, ma sono stato sorpreso di vedere che nessuno sembrava pubblicare una risposta che;
- Non ho utilizzato l'arrotondamento dei banchieri
- Non ha mantenuto il valore come decimale.
Questo è quello che vorrei usare:
decimal.Round(yourValue, 2, MidpointRounding.AwayFromZero);
decimalVar.ToString("F");
Questo:
- Arrotondare al secondo decimale, ad es. 23.456 = > 23.46
- Assicurati che lì sono sempre 2 decimali, ad es. 23 = > 23.00, 12.5 = > 12.50
Ideale per la valuta e la visualizzazione di importi monetari.
Per la documentazione su ToString (" F "): http://msdn.microsoft.com/en-us/library/dwhawy9k%28v=vs.110%29.aspx#FFormatString (grazie a Jon Schneider)
Se hai solo bisogno di questo per la visualizzazione usa string.Format
String.Format("{0:0.00}", 123.4567m); // "123.46"
http://www.csharp-examples.net/string-format-double /
Il " m " è un suffisso decimale. Informazioni sul suffisso decimale:
Dato decimale d = 12.345; le espressioni d.ToString (" C ") o String.Format (" {0: C} " ;, d) rendi $ 12,35 : tieni presente che vengono utilizzate le impostazioni di valuta della cultura corrente, incluso il simbolo.
Nota che " C " utilizza il numero di cifre della cultura corrente. Puoi sempre sostituire l'impostazione predefinita per forzare la precisione necessaria con C {Specificatore di precisione}
come String.Format (" {0: C2} " ;, 5.123d)
.
Se lo si desidera formattato con virgole e un punto decimale (ma senza simbolo di valuta), come 3.456.789,12 ...
decimalVar.ToString("n2");
Esistono già due risposte con punteggio elevato che fanno riferimento a Decimal.Round (...) ma penso che sia necessaria una spiegazione in più - perché c'è un'importante proprietà inaspettata di Decimal che non è ovvia.
Un decimale 'sa' quante posizioni decimali ha basato sulla sua provenienza.
Ad esempio, potrebbe essere imprevisto quanto segue:
Decimal.Parse("25").ToString() => "25"
Decimal.Parse("25.").ToString() => "25"
Decimal.Parse("25.0").ToString() => "25.0"
Decimal.Parse("25.0000").ToString() => "25.0000"
25m.ToString() => "25"
25.000m.ToString() => "25.000"
Se si eseguono le stesse operazioni con Double
non verranno assegnati decimali ( " 25 "
) per ciascuno dei precedenti.
Quando vuoi un decimale con 2 decimali c'è circa una probabilità del 95% è perché è la valuta, nel qual caso probabilmente va bene per il 95% delle volte:
Decimal.Parse("25.0").ToString("c") => "$25.00"
O in XAML basta usare {Binding Price, StringFormat = c}
Un caso in cui mi sono imbattuto in cui avevo bisogno di un decimale come un decimale è stato quando ho inviato XML al servizio web di Amazon. Il servizio si lamentava perché un valore decimale (originariamente da SQL Server) veniva inviato come 25.1200
e rifiutato, ( 25.12
era il formato previsto).
Tutto quello che dovevo fare era Decimal.Round (...)
con 2 cifre decimali per risolvere il problema.
// This is an XML message - with generated code by XSD.exe
StandardPrice = new OverrideCurrencyAmount()
{
TypedValue = Decimal.Round(product.StandardPrice, 2),
currency = "USD"
}
TypedValue
è di tipo Decimale
quindi non potevo semplicemente fare ToString (" N2 ")
e avevo bisogno di arrotondarlo e mantenere come decimale
.
Ecco un piccolo programma Linqpad per mostrare diversi formati:
void Main()
{
FormatDecimal(2345.94742M);
FormatDecimal(43M);
FormatDecimal(0M);
FormatDecimal(0.007M);
}
public void FormatDecimal(decimal val)
{
Console.WriteLine("ToString: {0}", val);
Console.WriteLine("c: {0:c}", val);
Console.WriteLine("0.00: {0:0.00}", val);
Console.WriteLine("0.##: {0:0.##}", val);
Console.WriteLine("===================");
}
Ecco i risultati:
ToString: 2345.94742
c: $2,345.95
0.00: 2345.95
0.##: 2345.95
===================
ToString: 43
c: $43.00
0.00: 43.00
0.##: 43
===================
ToString: 0
c: <*>.00
0.00: 0.00
0.##: 0
===================
ToString: 0.007
c: <*>.01
0.00: 0.01
0.##: 0.01
===================
Nessuno di questi ha fatto esattamente ciò di cui avevo bisogno, per forzare 2 d.p. e arrotondare per eccesso come 0.005 - > 0.01
Forcing 2 d.p. richiede un aumento della precisione di 2 d.p. per garantire che abbiamo almeno 2 d.p.
quindi arrotondamento per assicurarsi che non abbiamo più di 2 d.p.
Math.Round(exactResult * 1.00m, 2, MidpointRounding.AwayFromZero)
6.665m.ToString() -> "6.67"
6.6m.ToString() -> "6.60"
Molto raramente vorresti una stringa vuota se il valore è 0.
decimal test = 5.00;
test.ToString("0.00"); //"5.00"
decimal? test2 = 5.05;
test2.ToString("0.00"); //"5.05"
decimal? test3 = 0;
test3.ToString("0.00"); //"0.00"
La risposta più votata è errata e ha perso 10 minuti di tempo (la maggior parte) delle persone.
La risposta più votata descrive un metodo per formattare la rappresentazione di stringa del valore decimale e funziona.
Tuttavia, se si desidera effettivamente modificare la precisione salvata sul valore effettivo, è necessario scrivere qualcosa di simile al seguente:
public static class PrecisionHelper
{
public static decimal TwoDecimalPlaces(this decimal value)
{
// These first lines eliminate all digits past two places.
var timesHundred = (int) (value * 100);
var removeZeroes = timesHundred / 100m;
// In this implementation, I don't want to alter the underlying
// value. As such, if it needs greater precision to stay unaltered,
// I return it.
if (removeZeroes != value)
return value;
// Addition and subtraction can reliably change precision.
// For two decimal values A and B, (A + B) will have at least as
// many digits past the decimal point as A or B.
return removeZeroes + 0.01m - 0.01m;
}
}
Un esempio di unit test:
[Test]
public void PrecisionExampleUnitTest()
{
decimal a = 500m;
decimal b = 99.99m;
decimal c = 123.4m;
decimal d = 10101.1000000m;
decimal e = 908.7650m
Assert.That(a.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
Is.EqualTo("500.00"));
Assert.That(b.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
Is.EqualTo("99.99"));
Assert.That(c.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
Is.EqualTo("123.40"));
Assert.That(d.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
Is.EqualTo("10101.10"));
// In this particular implementation, values that can't be expressed in
// two decimal places are unaltered, so this remains as-is.
Assert.That(e.TwoDecimalPlaces().ToString(CultureInfo.InvariantCulture),
Is.EqualTo("908.7650"));
}
Puoi usare system.globalization per formattare un numero in qualsiasi formato richiesto.
Ad esempio:
system.globalization.cultureinfo ci = new system.globalization.cultureinfo("en-ca");
Se hai un decimale d = 1.2300000
e devi tagliarlo a 2 decimali, allora può essere stampato come questo d.Tostring (" F2 ", ci);
dove F2 sta formando una stringa con 2 cifre decimali e ci è la locale o cultureinfo.
per maggiori informazioni controlla questo link
http://msdn.microsoft.com/en-us/library/dwhawy9k.aspx
La risposta di Mike M. è stata perfetta per me su .NET, ma .NET Core non ha un
In .NET Core, ho dovuto usare:
decimal roundedValue = Math.Round(rawNumber, 2, MidpointRounding.AwayFromZero);
Un metodo hacky, inclusa la conversione in stringa, è:
public string FormatTo2Dp(decimal myNumber)
{
// Use schoolboy rounding, not bankers.
myNumber = Math.Round(myNumber, 2, MidpointRounding.AwayFromZero);
return string.Format("{0:0.00}", myNumber);
}
https://msdn.microsoft. com / it-it / library / dwhawy9k% 28v = vs.110% 29.aspx
Questo link spiega in dettaglio come gestire il tuo problema e cosa puoi fare se vuoi saperne di più. Per motivi di semplicità, quello che vuoi fare è
double whateverYouWantToChange = whateverYouWantToChange.ToString("F2");
se lo desideri per una valuta, puoi semplificarlo digitando " C2 " invece di " F2 "