296 Stimmen

Warum verwendet .NET standardmäßig die Rundung von Banken?

Laut der Dokumentation ist die decimal.Round Methode verwendet einen Round-to-even-Algorithmus, der für die meisten Anwendungen nicht üblich ist. Daher schreibe ich am Ende immer eine benutzerdefinierte Funktion, um den natürlicheren Algorithmus zum Aufrunden zu verwenden:

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;
}

Kennt jemand den Grund für diese Entscheidung zur Gestaltung des Rahmens?

Gibt es eine integrierte Implementierung des Round-Half-Up-Algorithmus in den Rahmen? Oder vielleicht eine nicht verwaltete Windows-API?

Für Anfänger könnte es irreführend sein, einfach zu schreiben decimal.Round(2.5m, 0) Sie erwarteten 3, bekamen aber nur 2.

458voto

Ostemar Punkte 5670

Die anderen Antworten mit Gründen, warum der Banker's Algorithmus (auch bekannt als Runde Hälfte bis gerade ) eine gute Wahl ist, sind völlig richtig. Sie leidet nicht so sehr unter negativen oder positiven Verzerrungen wie die Runde Hälfte weg von Null Methode über die meisten sinnvollen Verteilungen.

Aber die Frage war, warum .NET die tatsächliche Rundung von Banker als Standard verwendet - und die Antwort ist, dass Microsoft die IEEE 754 Standard. Dies wird auch erwähnt in MSDN für Math.Round unter "Bemerkungen".

Beachten Sie auch, dass .NET die von der IEEE spezifizierte alternative Methode unterstützt, indem es die MidpointRounding Aufzählung. Sie hätten natürlich auch mehr Alternativen zu lösen, aber sie entscheiden sich dafür, nur den IEEE-Standard zu erfüllen.

209voto

Kibbee Punkte 64039

Wahrscheinlich, weil es ein besserer Algorithmus ist. Im Laufe vieler Rundungen werden Sie feststellen, dass alle 0,5er gleichmäßig auf- und abgerundet werden. Dies führt zu besseren Schätzungen der tatsächlichen Ergebnisse, wenn Sie beispielsweise eine Reihe von gerundeten Zahlen addieren. Ich würde sagen, auch wenn es nicht das ist, was manche erwarten, ist es wahrscheinlich die korrektere Vorgehensweise.

91voto

Michael Stum Punkte 172055

Ich kann zwar nicht die Frage beantworten, warum die Designer von Microsoft dies als Standard gewählt haben, möchte aber darauf hinweisen, dass eine zusätzliche Funktion unnötig ist.

Math.Round ermöglicht die Angabe einer MidpointRounding :

  • ToEven - Wenn eine Zahl in der Mitte zwischen zwei anderen liegt, wird sie auf die nächste gerade Zahl gerundet.
  • AwayFromZero - Wenn eine Zahl in der Mitte zwischen zwei anderen liegt, wird sie auf die nächstliegende Zahl gerundet, die von Null entfernt ist.

23voto

Ian Ringrose Punkte 50437

Dezimalzahlen werden meist verwendet für Geld Die Rundung durch den Banker ist bei der Arbeit mit Geld . Oder man könnte sagen.

Es sind vor allem Banker, die die Dezimaltyp benötigen; deshalb macht es "Banker's rounding"

Rundungen haben den Vorteil, dass man im Durchschnitt das gleiche Ergebnis erhält, wenn man rundet:

  • eine Reihe von "Rechnungszeilen" zu runden, bevor sie addiert werden,
  • oder sie addieren und dann die Summe runden

Das Runden vor dem Aufaddieren sparte in der Zeit vor dem Computer viel Arbeit.

(Als wir im Vereinigten Königreich auf das Dezimalsystem umstellten, gaben die Banken keine halben Pence aus, aber viele Jahre lang gab es noch eine halbe Pence-Münze, und in den Geschäften endeten die Preise oft auf halbe Pence - es wurde also viel gerundet).

0voto

Omid Sadeghi Punkte 655

Verwenden Sie eine andere Überladung der Funktion Round wie diese:

decimal.Round(2.5m, 0,MidpointRounding.AwayFromZero)

Es wird ausgegeben 3 . Und wenn Sie

decimal.Round(2.5m, 0,MidpointRounding.ToEven)

erhalten Sie die Rundung der Bank.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X