round(value,significantDigit)
ist die gewöhnliche Lösung, aber dies funktioniert nicht wie man sich von einer mathematischen Perspektive erwarten würde, wenn runde Werte in 5
enden. Wenn der Wert 5
in der Zahl unmittelbar hinter der Zahl liegt, auf die Sie gerundet werden, werden diese Werte nur manchmal wie erwartet aufgerundet (d. H. 8.005
, das Runden auf zwei Dezimalziffern ergibt 8.01
). Für bestimmte Werte aufgrund der Eigenarten der Fließkomma-Mathematik werden sie stattdessen abgerundet!
d.h.
>>> round(1.0005,3)
1.0
>>> round(2.0005,3)
2.001
>>> round(3.0005,3)
3.001
>>> round(4.0005,3)
4.0
>>> round(1.005,2)
1.0
>>> round(5.005,2)
5.0
>>> round(6.005,2)
6.0
>>> round(7.005,2)
7.0
>>> round(3.005,2)
3.0
>>> round(8.005,2)
8.01
Schräge.
Angenommen, Ihre Absicht ist es, die traditionelle Abrundung für die Statistik in den Wissenschaften zu tun, ist dies eine praktische Wrapper arbeiten, um die round
Funktion zu erhalten, wie wie Decimal
-import
Extramaterial zu erwarten zu müssen.
>>> round(0.075,2)
0.07
>>> round(0.075+10**(-2*5),2)
0.08
Aha! So auf dieser Grundlage wir eine Funktion machen kann ...
def roundTraditional(val,digits):
return round(val+10**(-len(str(val))-1))
Grundsätzlich fügt dieser Wert garantiert, dass er kleiner ist als der am wenigsten gegeben Ziffer der Zeichenfolge Sie versuchen round
auf zu verwenden. Durch das Hinzufügen dieser kleinen Menge wird das Verhalten der round
in den meisten Fällen beibehalten, während nun sichergestellt wird, dass die Ziffer, die der abgerundeten Zahl 5
entspricht, rundet und wenn sie 4
ist, rundet sie ab.
Der Ansatz von 10**(-len(val)-1)
mit Absicht war, wie es die größte kleine Zahl, die Sie den Übergang zu zwingen hinzufügen können, aber auch, dass der Wert, den Sie nie ändert sich die Rundung auch wenn das Dezimalsystem .
fehlt hinzufügen zu gewährleisten. Ich könnte nur 10**(-len(val))
mit einem bedingten if (val>1)
verwenden, um 1
zu subtrahieren mehr ... aber es ist einfacher, nur die 1
subtrahieren als das wird nicht viel den anwendbaren Bereich von Dezimalzahlen ändern diese Problemumgehung kann richtig umgehen. Dieser Ansatz wird fehlschlagen, wenn Ihre Werte die Grenzen des Typs erreichen, dies wird fehlschlagen, aber für fast den gesamten Bereich der gültigen Dezimalwerte sollte es funktionieren.
Sie können auch die decimal-Bibliothek verwenden, um dies zu erreichen, aber der von mir vorgeschlagene Wrapper ist einfacher und kann in einigen Fällen bevorzugt werden.
Edit: Dank Blckknght für den Hinweis auf, dass der 5
fringe Fall nur für bestimmte Werte auftritt. Auch eine frühere Version dieser Antwort war nicht explizit genug, dass das ungerade Rundungsverhalten nur dann auftritt, wenn die Stelle, die unmittelbar hinter der Ziffer liegt, auf die Sie gerundet werden, eine 5
hat.
Ich würde versuchen, 'int (x)' –