Zgodnie z dokumentacją decimal.Round
metoda wykorzystuje algorytm zaokrąglania do parzystości, który nie jest powszechny w większości aplikacji. Dlatego zawsze kończę na napisaniu niestandardowej funkcji, aby wykonać bardziej naturalny algorytm zaokrąglania do połowy:
public static decimal RoundHalfUp(this decimal d, int decimals)
{
if (decimals < 0)
{
throw new ArgumentException("The decimals must be non-negative",
"decimals");
}
decimal multiplier = (decimal)Math.Pow(10, decimals);
decimal number = d * multiplier;
if (decimal.Truncate(number) < number)
{
number += 0.5m;
}
return decimal.Round(number) / multiplier;
}
Czy ktoś zna przyczynę tej decyzji dotyczącej projektu ramowego?
Czy jest jakaś wbudowana implementacja algorytmu zaokrąglania do połowy w strukturze? A może jakiś niezarządzany interfejs Windows API?
Może to być mylące dla początkujących, którzy po prostu piszą, decimal.Round(2.5m, 0)
oczekując 3, ale zamiast tego otrzymują 2.
Odpowiedzi:
Prawdopodobnie dlatego, że jest to lepszy algorytm. W trakcie wielu zaokrągleń uśredniasz, że wszystkie .5 kończą zaokrąglanie równo w górę i w dół. To daje lepsze oszacowania rzeczywistych wyników, jeśli na przykład dodajesz kilka zaokrąglonych liczb. Powiedziałbym, że chociaż nie jest to, czego niektórzy mogą się spodziewać, to prawdopodobnie bardziej właściwa rzecz do zrobienia.
źródło
Inne odpowiedzi z powodów, dla których algorytm bankiera (czyli półokrągły do parzystego ) jest dobrym wyborem, są całkiem poprawne. Nie ma negatywnego lub pozytywnego nastawienia tak bardzo, jak okrągła połowa odległości od metody zerowej w najbardziej rozsądnych rozkładach.
Pytanie brzmiało jednak, dlaczego .NET domyślnie korzysta z faktycznego zaokrąglania przez Banker - a odpowiedź brzmi: Microsoft przestrzegał standardu IEEE 754 . Jest to również wspomniane w MSDN dla Math.Round pod uwagami .
Należy również pamiętać, że .NET obsługuje alternatywną metodę określoną przez IEEE, podając
MidpointRounding
wyliczenie. Mogliby oczywiście zapewnić więcej alternatyw dla rozwiązywania więzi, ale wybrali po prostu spełnienie standardu IEEE.źródło
Chociaż nie mogę odpowiedzieć na pytanie „Dlaczego projektanci Microsoftu wybrali tę opcję jako domyślną?”, Chcę jedynie zaznaczyć, że dodatkowa funkcja nie jest potrzebna.
Math.Round
pozwala określićMidpointRounding
:źródło
Dziesiętne są najczęściej używane do pieniędzy ; zaokrąglanie przez bankiera jest powszechne podczas pracy z pieniędzmi . Lub możesz powiedzieć.
Zaokrąglanie przez bankierów ma tę zaletę, że średnio ten sam wynik uzyskasz, jeśli:
Zaokrąglanie przed zsumowaniem pozwoliło zaoszczędzić sporo pracy w dniach poprzedzających komputery.
(W Wielkiej Brytanii, kiedy szliśmy po przecinku, banki nie radziły sobie z pół pensami, ale przez wiele lat wciąż było pół pensów, a sklep często miał ceny kończące się na pół pensów - więc zaokrąglanie)
źródło
Decmial
s tak Dziesiętne, nie. Dla potomnych zgadzam się z oryginalnym sentymentem tutaj.Użyj innego przeciążenia funkcji Round:
Wyjdzie 3 . A jeśli użyjesz
dostaniesz zaokrąglenie bankiera.
źródło