Sirius3 hat geschrieben: ↑Montag 7. Dezember 2020, 18:25
Wenn man als Defaultwert ndigits=0 wählt, braucht man auch keine Sonderbehandlung.
Das hätte ich wahrscheinlich sogar gemacht, wenn ich nicht einfach die Signatur von round kopiert hätte.
Dort ist komischerweise None der Standardwert, aber round ist ja in C implementiert.
Die Funktion round liefert ein int zurück, wenn ndigits ein None ist und wenn man ndigits angibt (int), bekommt man einen float.
Das hatte ich in der kround nicht implementiert und an negative Zahlen habe ich erst gar nicht gedacht.
Eine weitere Sache, die man wissen sollte, wie divmod funktioniert und speziell bei negativen Zahlen ist es etwas komisch.
Damit ich keinen Knoten im Kopf bekomme, nehme ich jetzt den Betrag (abs) und copiere vorher noch das Vorzeichen.
Das mit dem None habe ich auch drin gelassen, aber so erweitert, dass bei None immer ein Int zurückgeliefert wird.
Den Docstring habe ich zur Hälfte von Wikipedia geklaut.
Code: Alles auswählen
def kround(number, ndigits=None):
"""
Kaufmännisches runden.
Liefert einen int zurück, wenn
ndigits == None
Ansonsten gibt ndigits die
Stellen hinter dem Komma an und
ein Float wird zurück gegeben.
Das Kaufmännische Runden (nicht negativer Zahlen) geschieht wie folgt:
- Ist die Ziffer an der ersten wegfallenden
Dezimalstelle eine 0, 1, 2, 3 oder 4,
dann wird abgerundet.
- Ist die Ziffer an der ersten wegfallenden
Dezimalstelle eine 5, 6, 7, 8 oder 9,
dann wird aufgerundet.
13.3749 € ≈ 13.37 €
13.3750 € ≈ 13.38 €
>>> kround(13.3749, 2)
13.37
>>> kround(13.3750, 2)
13.38
Negative Zahlen werden nach ihrem Betrag gerundet,
bei einer 5 also weg von null (engl: Away from Zero)
-13.3749 € ≈ -13.37 €
-13.3750 € ≈ -13.38 €
>>> kround(-13.3749, 2)
-13.37
>>> kround(-13.3750, 2)
-13.38
Diese Rundungsregel wird durch die Norm DIN 1333 beschrieben.
"""
sign = -1 if number < 0 else 1
if ndigits is not None:
exponent = 10 ** ndigits
else:
exponent = 1
number *= exponent
number, rest = divmod(abs(number), 1)
if rest >= 0.5:
number += 1
number /= exponent
number *= sign
if ndigits is None:
return int(number)
else:
return number
Wenn man die Funktion verschönern will, beseitigt man am besten den Spezialfall None.
PS: Wer mag, kann ja ein Unittest schreiben. Aber Anfänger wollen sich wahrscheinlich damit nicht so lange aufhalten.
PPS: ndigits könnte auch negativ sein. Auch nicht getestet

sourceserver.info - sourceserver.info/wiki/ - ausgestorbener Support für HL2-Server