Ich habe gelernt, dass Python nicht kaufmännisch rundet!

Was ist kaufmännisches Runden?

Für die meisten Zahlen ist klar, wohin sie gerundet werden. Es gibt allerdings Spezialfälle - insbesondere: Wenn ich $0.5$ runde, wird das $0$ oder $1$?

Kaufmännisches Runden löst das Problem mit der Regel “Weg von Null”, daher: Aufrunden bei positiven Nummern, abrunden bei negativen Nummern.

Für Mathematiker dürfte das genügen, für alle anderen gibt es hier noch Beispiele1:

  • $0.5$ wird $1$.
  • $-0.5$ wird $-1$ (weg von Null!).

In anderen Potenzen gilt offensichtlich das gleiche, so wird $0.05$ zu $0.1$, etc.

Was macht Python stattdessen?

Python nutzt mathematisches Runden: Runde zur nächsten geraden Zahl. Also:

  • $0.5$ wird $0$ (!).
  • $1.5$ wird $2$.
  • $2.5$ wird $2$ (!).

Es gibt Situationen wo das sinnvoll ist; das werde ich in einem späteren Post diskutieren.

Wie runde ich dann in Python kaufmännisch?

Ich habe mir einfach eine Funktion geschrieben, die das für mich macht. Die kann ich auch direkt statt der eingebauten round Funktion verwenden, und zumindest in meinem Setting muss ich nichts umstellen:

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
def round(val, ndigits=0):

    # Vorzeichen merken, um weniger
    # Fallunterscheidungen machen zu müssen
    sign = 1 if val >= 0 else -1

    factor = 10**ndigits

    scaled = int(val * sign * factor * 10)
    last_digit = scaled % 10

    scaled = scaled // 10

    # Hier passiert das Runden: Aufrunden
    # wenn nötig, sonst abrunden (bzw. 
    # nichts tun)
    if last_digit >= 5:
        scaled += 1

    # Wenn wir auf Ganzzahlen runden, gib auch
    # eine Ganzzahl zurück
    if ndigits == 0:
        return int(scaled * sign)

    # Ansonsten, gib die korrekte
    # Gleitkommazahl zurück
    return scaled * sign / factor

Definiere diese Funktion einfach am Anfang des Moduls, und nutze dann round so wie vorher auch.

Beachte!

Ganz sicher bin ich mir ob meines Ansatzes noch nicht. Am Ende kommt immerhin doch wieder eine Gleitkommazahl heraus, die potentiell inkorrekt dargestellt wird - wie verhindere ich das?


  1. Diese Aussage habe ich einmal in einem Paper gelesen, und das hat mich belustigt. Sorry an alle die das nicht lustig finden. ↩︎