Risposte:
Ecco alcuni esempi:
decimal a = 1.994444M;
Math.Round(a, 2); //returns 1.99
decimal b = 1.995555M;
Math.Round(b, 2); //returns 2.00
Potresti anche voler esaminare l'arrotondamento dei banchieri / round-to-even con il seguente sovraccarico:
Math.Round(a, 2, MidpointRounding.ToEven);
Ci sono maggiori informazioni qui .
0.005
al numero prima di arrotondare. Allo stesso modo per arrotondare per difetto, sottrarre 0.005
prima di passare alla Math.Round
funzione.
MidPointRounding.ToEven
(noto anche come "arrotondamento dei banchieri") è perché tutti abbiamo imparato a arrotondare a scuola dove il arrotondamento .5 causa un eccesso di arrotondamento. Questo è un problema quando si tratta di soldi, calcoli fiscali, ecc.
Prova questo:
twoDec = Math.Round(val, 2)
Personalmente non giro mai nulla. Tienilo il più risoluto possibile, dato che l'arrotondamento è comunque un po 'un'aringa rossa in CS. Ma vuoi formattare i dati per i tuoi utenti e, a tal fine, trovo che string.Format("{0:0.00}", number)
sia un buon approccio.
Se desideri una stringa
> (1.7289).ToString("#.##")
"1.73"
O un decimale
> Math.Round((Decimal)x, 2)
1.73m
Ma ricorda! L'arrotondamento non è distributivo, vale a dire. round(x*y) != round(x) * round(y)
. Quindi non eseguire alcun arrotondamento fino alla fine di un calcolo, altrimenti perderai la precisione.
Wikipedia ha una bella pagina sull'arrotondamento in generale.
Tutte le lingue .NET (gestite) possono utilizzare qualsiasi meccanismo di arrotondamento del Common Language Run Time (CLR). Ad esempio, il metodo Math.Round () (come menzionato sopra) consente allo sviluppatore di specificare il tipo di arrotondamento (Arrotondato a pari o Assente da zero). Il metodo Convert.ToInt32 () e le sue variazioni utilizzano il round-to-even . I metodi Ceiling () e Floor () sono correlati.
Puoi arrotondare anche con una formattazione numerica personalizzata .
Si noti che Decimal.Round () utilizza un metodo diverso da Math.Round ();
Ecco una posizione utile sull'algoritmo di arrotondamento del banchiere. Guarda uno dei post umoristici di Raymond qui sull'arrotondamento ...
// converte fino a due cifre decimali
String.Format("{0:0.00}", 140.6767554); // "140.67"
String.Format("{0:0.00}", 140.1); // "140.10"
String.Format("{0:0.00}", 140); // "140.00"
Double d = 140.6767554;
Double dc = Math.Round((Double)d, 2); // 140.67
decimal d = 140.6767554M;
decimal dc = Math.Round(d, 2); // 140.67
=========
// just two decimal places
String.Format("{0:0.##}", 123.4567); // "123.46"
String.Format("{0:0.##}", 123.4); // "123.4"
String.Format("{0:0.##}", 123.0); // "123"
può anche combinare "0" con "#".
String.Format("{0:0.0#}", 123.4567) // "123.46"
String.Format("{0:0.0#}", 123.4) // "123.4"
String.Format("{0:0.0#}", 123.0) // "123.0"
So che è una vecchia domanda, ma per favore nota per le seguenti differenze tra round Math e round String :
decimal d1 = (decimal)1.125;
Math.Round(d1, 2).Dump(); // returns 1.12
d1.ToString("#.##").Dump(); // returns "1.13"
decimal d2 = (decimal)1.1251;
Math.Round(d2, 2).Dump(); // returns 1.13
d2.ToString("#.##").Dump(); // returns "1.13"
Se vuoi arrotondare un numero, puoi ottenere risultati diversi a seconda di: come usi la funzione Math.Round () (se per un arrotondamento per eccesso o per difetto), stai lavorando con numeri doppi e / o float e si applica l'arrotondamento del punto medio. Soprattutto, quando si utilizza con operazioni al suo interno o la variabile da arrotondare proviene da un'operazione. Diciamo, vuoi moltiplicare questi due numeri: 0,75 * 0,95 = 0,7125 . Giusto? Non in C #
Vediamo cosa succede se vuoi arrotondare al terzo decimale:
double result = 0.75d * 0.95d; // result = 0.71249999999999991
double result = 0.75f * 0.95f; // result = 0.71249997615814209
result = Math.Round(result, 3, MidpointRounding.ToEven); // result = 0.712. Ok
result = Math.Round(result, 3, MidpointRounding.AwayFromZero); // result = 0.712. Should be 0.713
Come vedi, il primo Round () è corretto se vuoi arrotondare il punto medio. Ma il secondo Round () è sbagliato se vuoi arrotondare.
Questo vale per i numeri negativi:
double result = -0.75 * 0.95; //result = -0.71249999999999991
result = Math.Round(result, 3, MidpointRounding.ToEven); // result = -0.712. Ok
result = Math.Round(result, 3, MidpointRounding.AwayFromZero); // result = -0.712. Should be -0.713
Quindi, IMHO, dovresti creare la tua funzione di avvolgimento per Math.Round () adatta alle tue esigenze. Ho creato una funzione in cui, il parametro 'roundUp = true' significa arrotondare al numero maggiore successivo. Cioè: 0,7125 round a 0,713 e -0,7125 round a -0,712 (perché -0,712> -0,713). Questa è la funzione che ho creato e funziona per qualsiasi numero di decimali:
double Redondea(double value, int precision, bool roundUp = true)
{
if ((decimal)value == 0.0m)
return 0.0;
double corrector = 1 / Math.Pow(10, precision + 2);
if ((decimal)value < 0.0m)
{
if (roundUp)
return Math.Round(value, precision, MidpointRounding.ToEven);
else
return Math.Round(value - corrector, precision, MidpointRounding.AwayFromZero);
}
else
{
if (roundUp)
return Math.Round(value + corrector, precision, MidpointRounding.AwayFromZero);
else
return Math.Round(value, precision, MidpointRounding.ToEven);
}
}
La variabile 'correttore' serve a correggere l'imprecisione di operare con numeri mobili o doppi.
Una cosa che potresti voler controllare è il meccanismo di arrotondamento della matematica.
http://msdn.microsoft.com/en-us/library/system.midpointrounding.aspx
Oltre a ciò, raccomando l'approccio Math.Round (inputNumer, numberOfPlaces) rispetto a quello * 100/100 perché è più pulito.
Dovresti essere in grado di specificare il numero di cifre che vuoi arrotondare usando Math.Round (YourNumber, 2)
Puoi leggere di più qui .
Math.Floor (123456.646 * 100) / 100 Restituire 123456.64
stringa a = "10.65678";
decimale d = Math.Round (Convert.ToDouble (a.ToString ()), 2)
Ho avuto una strana situazione in cui avevo una variabile decimale, quando serializza 55.50 imposta sempre matematicamente il valore predefinito come 55,5. Ma considerando che il nostro sistema client prevede seriamente 55,50 per qualche motivo e si aspettavano sicuramente decimali. Quello è quando avevo scritto l'helper di seguito, che converte sempre qualsiasi valore decimale imbottito in 2 cifre con zeri invece di inviare una stringa.
public static class DecimalExtensions
{
public static decimal WithTwoDecimalPoints(this decimal val)
{
return decimal.Parse(val.ToString("0.00"));
}
}
L'uso dovrebbe essere
var sampleDecimalValueV1 = 2.5m;
Console.WriteLine(sampleDecimalValueV1.WithTwoDecimalPoints());
decimal sampleDecimalValueV1 = 2;
Console.WriteLine(sampleDecimalValueV1.WithTwoDecimalPoints());
Produzione:
2.50
2.00