2010-02-16 15 views

Antwort

188

Ich weiß nicht, von einer Standardfunktion in Python, aber das funktioniert für mich :

def myround(x, base=5): 
    return int(base * round(float(x)/base)) 

Es ist leicht zu sehen, warum das obige funktioniert. Sie möchten sicherstellen, dass Ihre durch 5 geteilte Zahl eine ganze Zahl ist, richtig gerundet. Also machen wir zuerst genau das (round(float(x)/5)), und dann, da wir durch 5 geteilt haben, multiplizieren wir auch mit 5. Die letzte Konvertierung in int erfolgt, weil round() einen Gleitkommawert in Python zurückgibt.

machte ich die Funktion allgemeineren durch einen base Parameter geben, bis 5. säumige

+1

Wenn nur ganze Zahlen und Abrunden, dann kannst du auch 'x // base * base' machen – Tjorriemorrie

+1

das bin ich paranoid, aber ich bevorzuge' floor() 'und' ceil() 'anstatt Casting: 'base * floor (x/base)' – user666412

18

Es ist nur eine Frage der Skalierung

>>> a=[10,11,12,13,14,15,16,17,18,19,20] 
>>> for b in a: 
...  int(round(b/5.0)*5.0) 
... 
10 
10 
10 
15 
15 
15 
15 
15 
20 
20 
20 
5

Runde (x [n]): Werte gerundet werden zum nächsten Vielfachen von 10 zur Macht minus n. Also, wenn n negativ ist ...

def round5(x): 
    return int(round(x*2, -1))/2 

Seit 10 = 5 * 2 können Sie Integer-Division und Multiplikation mit 2, anstatt float Division und Multiplikation mit 5,0 verwenden. dass nicht so viel zählt, es sei denn, Sie wenig wie Verschiebung

def round5(x): 
    return int(round(x << 1, -1)) >> 1 
+1

+1, um uns zu zeigen, dass round() das Runden auf andere Multiples als 1.0 verarbeiten kann, einschließlich höherer Werte. (Beachten Sie jedoch, dass der Bit-Shifting-Ansatz nicht mit Floats funktioniert, ganz zu schweigen davon, dass er für die meisten Programmierer weniger lesbar ist.) –

+1

@Peter Hansen bedankt sich für die +1.Benötigen Sie ein int (x) für die Bitverschiebung, um mit Floats zu arbeiten. Vereinbart nicht die am besten lesbaren und ich würde es nicht selbst verwenden, aber ich mochte die "Reinheit" davon nur mit 1 und nicht 2 oder 5. – pwdyson

0

Was dazu:

def divround(value, step): 
    return divmod(value, step)[0] * step 
+0

Verdammt, das war nicht die Frage ... aber ich habe es modifiziert (siehe modifizierte Version!). –

+0

Was ist Divmod? –

3

modifizierte Version von divround :-)

def divround(value, step, barrage): 
    result, rest = divmod(value, step) 
    return result*step if rest < barrage else (result+1)*step 
+0

also in diesem Fall verwenden Sie divround (Wert, 5, 3)? oder vielleicht divround (Wert, 5, 2.5)? – pwdyson

+0

divround (Wert, 5, 3), genau. –

10

Entfernen der 'Rest' funktionieren würde, :

rounded = int(val) - int(val) % 5 

Wenn der Wert aready eine ganze Zahl:

rounded = val - val % 5 

Als Funktion:

def roundint(value, base=5): 
    return int(value) - int(value) % int(base) 
+0

Dies funktioniert nur zum Abrunden. – Craig

+0

Ich mag diese Antwort zum Runden auf den nächsten Bruchwert. wenn ich nur Inkremente von 0,25 wünschen. –

23

Denn für nicht ganzzahlige Werte gerundet, wie beispielsweise 0,05:

def myround(x, prec=2, base=.05): 
    return round(base * round(float(x)/base),prec) 

I dies nützlich, da ich gefunden könnte einfach in meinem code suchen und ersetzen, um "round (" zu "myround (") zu ändern, ohne die Parameterwerte ändern zu müssen.

-3

Sie können „Trick“ int() in Auf- oder Abrundung statt nach unten der Rundung von 0.5 auf die Zahl Hinzufügen Sie int() passieren.

+1

Dies beantwortet nicht wirklich die Frage –

3

Sorry, wollte ich auf Alok Singhai Antwort kommentieren, aber es wird mich nicht wegen eines Mangels an Reputation lassen =/

Wie auch immer, können wir einen weiteren Schritt verallgemeinern und gehen:

def myround(x, base=5): 
    return base * round(float(x)/base) 

Dies erlaubt uns, nicht-ganzzahlige Basen zu verwenden, wie .25 oder jede andere gebrochene Base.

2

Ich weiß, ich auf die Party zu spät komme, aber es scheint, dass diese Lösung nicht erwähnt worden:

>>> from __future__ import division # This is only needed on Python 2 
>>> def round_to_nearest(n, m): 
     r = n % m 
     return n + m - r if r + r >= m else n - r 

... 

Es ist nicht Multiplikation nicht verwendet und wird nicht von/nach Schwimmern konvertieren.

Rundung auf das nächste Vielfache von 10:

>>> for n in range(-21, 30, 3): print('{:3d} => {:3d}'.format(n, round_to_nearest(n, 10))) 
-21 => -20 
-18 => -20 
-15 => -10 
-12 => -10 
-9 => -10 
-6 => -10 
-3 => 0 
    0 => 0 
    3 => 0 
    6 => 10 
    9 => 10 
12 => 10 
15 => 20 
18 => 20 
21 => 20 
24 => 20 
27 => 30 

Wie Sie sehen können, es funktioniert für sowohl negative als auch positive Zahlen. Bindungen (z. B. -15 und 15) werden immer nach oben gerundet.

ähnliches Beispiel, das nicht das nächste Vielfache von 5 Runden, was zeigt, dass es auch für eine andere „Basis“ wie erwartet verhält:

>>> for n in range(-21, 30, 3): print('{:3d} => {:3d}'.format(n, round_to_nearest(n, 5))) 
-21 => -20 
-18 => -20 
-15 => -15 
-12 => -10 
-9 => -10 
-6 => -5 
-3 => -5 
    0 => 0 
    3 => 5 
    6 => 5 
    9 => 10 
12 => 10 
15 => 15 
18 => 20 
21 => 20 
24 => 25 
27 => 25 
2
def round_to_next5(n): 
    return n + (5 - n) % 5 
-1

** nächste Vielfache von 5 **

betrachten 51 Notwendigkeit zu 55 umgewandelt

code here 

mark=51; 
r=100-mark; 
a=r%5; 
new_mark=mark+a; 
+0

Ist das eine Antwort oder eine andere Frage? –

1

Falls jemand „finanziellen Runden“ (0,5 Runden benötigt immer nach oben):

def myround(x, base=5): 
    roundcontext = decimal.Context(rounding=decimal.ROUND_HALF_UP) 
    decimal.setcontext(roundcontext) 
    return int(base *float(decimal.Decimal(x/base).quantize(decimal.Decimal('0')))) 

Per Dokumentation andere Rundungsoptionen sind:

ROUND_CEILING (in Richtung Unendlichkeit),
ROUND_DOWN (gegen Null),
ROUND_FLOOR (Richtung -Infinity),
ROUND_HALF_DOWN (zum nächsten mit Verbindungen, die gegen Null gehen),
ROUND_HALF_EVEN (zum nächsten mit Verbindungen zur nächsten geraden ganzen Zahl),
ROUND_HALF_UP (t o am nächsten mit Bindungen weg von Null), oder
ROUND_UP (weg von Null).
ROUND_05UP (weg von Null, wenn letzte Ziffer nach gegen Null Rundung 0 oder 5 gewesen wäre, andernfalls gegen Null)

standardmäßig Python verwendet ROUND_HALF_EVEN wie es einige statistische Vorteile (die abgerundeten Ergebnisse sind nicht voreingenommen) hat .