Jak zaokrąglić liczbę do dwóch miejsc po przecinku w C #?


Odpowiedzi:


629

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 .


51
Należy wyjaśnić, że MidPointRounding.ToEven IS jest wartością domyślną. Jeśli chcesz AwayFromZero, musisz użyć przeciążenia
Brian Vander Plaats

5
Jeśli chcesz zaokrąglić w górę do 2 miejsc po przecinku, dodaj 0.005liczbę przed zaokrągleniem. Podobnie zaokrąglić w dół , odejmij 0.005przed przejściem do Math.Roundfunkcji.
orad

4
Powodem, dla którego .NET domyślnie jest 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.
asporter


33

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.


Działa to lepiej do celów wyświetlania, szczególnie dla pieniędzy, ponieważ 5,4 GBP (z Math.round) nie wygląda tak dobrze, jak 5,40 GBP (w ten sposób).
Peter Gordon,

Próbowałem przed string.Format („0: 0.00”, liczba), ale to nie działało. Te nawiasy kwadratowe są bardzo ważne, więc: string.Format („{0: 0,00}”, liczba) działa.
FrenkyB

8
@FrenkyB Kiedy mówisz „nawiasy kwadratowe”, mam nadzieję, że masz na myśli nawiasy klamrowe.
Matematyki,

Ta runda również. 1,009 => 1,01
Donny V.

30

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ść.


14

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 ...


13

// 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"

1
String.Format ("{0: 0,00}", 140,6767554); ! = "140,67" W rzeczywistości jest renderowany jako "140,68" - zaokrąglenie w górę
AndyT

7

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"

6

Jest to zaokrąglenie do 2 miejsc po przecinku w C #:

label8.Text = valor_cuota .ToString("N2") ;

W VB.NET:

 Imports System.Math
 round(label8.text,2)

5

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.



3

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 .




1

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

0
  public double RoundDown(double number, int decimalPlaces)
        {
            return Math.Floor(number * Math.Pow(10, decimalPlaces)) / Math.Pow(10, decimalPlaces);
        }
Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.