Odpowiedzi:
Oto kilka przykładów:
decimal a = 1.994444M;
Math.Round(a, 2); //returns 1.99
decimal b = 1.995555M;
Math.Round(b, 2); //returns 2.00
Możesz także przyjrzeć się bankierom zaokrąglającym / zaokrąglającym do nawet z następującym przeciążeniem:
Math.Round(a, 2, MidpointRounding.ToEven);
Więcej informacji na ten temat tutaj .
0.005
liczbę przed zaokrągleniem. Podobnie zaokrąglić w dół , odejmij 0.005
przed przejściem do Math.Round
funkcji.
MidPointRounding.ToEven
(inaczej „Zaokrąglanie banków”), jest to, że wszyscy nauczyliśmy się zaokrąglać w szkole, w której .5 zaokrągleń w górę powoduje zbyt duże zaokrąglanie w górę. Jest to problem w przypadku pieniędzy, obliczeń podatkowych itp.
Spróbuj tego:
twoDec = Math.Round(val, 2)
Osobiście nigdy niczego nie obchodzę. Staraj się, aby była jak najbardziej zdecydowana, ponieważ i tak zaokrąglanie jest trochę czerwonym śledziem w CS. Ale chcesz sformatować dane dla swoich użytkowników i w tym celu uważam, że string.Format("{0:0.00}", number)
jest to dobre podejście.
Jeśli chcesz ciąg
> (1.7289).ToString("#.##")
"1.73"
Lub dziesiętny
> Math.Round((Decimal)x, 2)
1.73m
Ale pamiętaj! Zaokrąglanie nie ma charakteru dystrybucyjnego, tzn. round(x*y) != round(x) * round(y)
. Nie rób więc zaokrąglania do samego końca obliczeń, w przeciwnym razie stracisz dokładność.
Wikipedia ma ogólnie dobrą stronę na temat zaokrąglania.
Wszystkie języki (zarządzane) .NET mogą używać dowolnego z mechanizmów zaokrąglania w czasie wykonywania wspólnego języka (CLR). Na przykład metoda Math.Round () (jak wspomniano powyżej) umożliwia deweloperowi określenie rodzaju zaokrąglania (zaokrąglenie do parzystej lub zera od zera). Metoda Convert.ToInt32 () i jej odmiany wykorzystują zaokrąglanie do parzystości . Metody Ceiling () i Floor () są powiązane.
Możesz zaokrąglać również niestandardowe formatowanie numeryczne .
Zauważ, że Decimal.Round () używa innej metody niż Math.Round ();
Oto przydatna pozycja algorytmu zaokrąglania bankiera. Zobacz jeden z humorystycznych postów Raymonda tutaj o zaokrąglaniu ...
// zamień do dwóch miejsc po przecinku
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"
można także łączyć „0” z „#”.
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"
Wiem, że to stare pytanie, ale zwróć uwagę na następujące różnice między rundą matematyczną i rundą ciągów znaków :
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"
Jeśli chcesz zaokrąglić liczbę, możesz uzyskać różne wyniki w zależności od: w jaki sposób korzystasz z funkcji Math.Round () (w przypadku zaokrąglania w górę lub w dół), pracujesz z liczbami podwójnymi i / lub liczbami zmiennoprzecinkowymi i zastosujesz zaokrąglenie punktu środkowego. Zwłaszcza, gdy używa się z operacjami wewnątrz niego lub zmienną do zaokrąglenia pochodzi z operacji. Powiedzmy, że chcesz pomnożyć te dwie liczby: 0,75 * 0,95 = 0,7125 . Dobrze? Nie w C #
Zobaczmy, co się stanie, jeśli chcesz zaokrąglić do trzeciego miejsca po przecinku:
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
Jak widać, pierwsza runda () jest poprawna, jeśli chcesz zaokrąglić w dół punkt środkowy. Ale druga runda () jest błędna, jeśli chcesz zaokrąglić w górę.
Dotyczy to liczb ujemnych:
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
Tak więc, IMHO, powinieneś stworzyć własną funkcję zawijania dla Math.Round (), która spełni twoje wymagania. Stworzyłem funkcję, w której parametr „roundUp = true” oznacza zaokrąglanie do następnej większej liczby. To znaczy: 0,7125 zaokrągla do 0,713 i -0,7125 zaokrągla do -0,712 (ponieważ -0,712> -0,713). Jest to funkcja, którą utworzyłem i działa dla dowolnej liczby miejsc po przecinku:
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);
}
}
Zmienna „korektor” służy do ustalania niedokładności działania liczb zmiennoprzecinkowych lub podwójnych.
Jedną z rzeczy, które możesz chcieć sprawdzić, jest mechanizm zaokrąglania matematyki.
http://msdn.microsoft.com/en-us/library/system.midpointrounding.aspx
Poza tym polecam podejście Math.Round (inputNumer, numberOfPlaces) nad * 100/100, ponieważ jest czystsze.
Powinieneś być w stanie określić liczbę cyfr, którą chcesz zaokrąglić za pomocą Math.Round (YourNumber, 2)
Możesz przeczytać więcej tutaj .
Math.Floor (123456.646 * 100) / 100 Zwróci 123456.64
ciąg a = „10.65678”;
dziesiętny d = Math.Round (Convert.ToDouble (a.ToString ()), 2)
Miałem dziwną sytuację, w której miałem zmienną dziesiętną, kiedy serializując 55,50, zawsze ustawia ona wartość domyślną matematycznie na 55,5. Ale podczas gdy nasz system kliencki z jakiegoś powodu poważnie oczekuje 55,50 i na pewno spodziewali się po przecinku. Tak było, gdy miałem napisać pomocnika, który zawsze konwertuje każdą wartość dziesiętną dopełnioną do 2 cyfr zerami zamiast wysyłać ciąg znaków.
public static class DecimalExtensions
{
public static decimal WithTwoDecimalPoints(this decimal val)
{
return decimal.Parse(val.ToString("0.00"));
}
}
Zastosowanie powinno być
var sampleDecimalValueV1 = 2.5m;
Console.WriteLine(sampleDecimalValueV1.WithTwoDecimalPoints());
decimal sampleDecimalValueV1 = 2;
Console.WriteLine(sampleDecimalValueV1.WithTwoDecimalPoints());
Wynik:
2.50
2.00