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.