2010-02-16 5 views

Répondre

188

Je ne sais pas d'une fonction standard en Python, mais cela fonctionne pour moi :

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

Il est facile de voir pourquoi ce qui précède fonctionne. Vous voulez vous assurer que votre nombre divisé par 5 est un nombre entier, correctement arrondi. Donc, nous faisons d'abord exactement cela (round(float(x)/5)), puis comme nous avons divisé par 5, nous multiplions par 5 ainsi. La conversion finale en int est due au fait que round() renvoie une valeur à virgule flottante en Python.

J'ai fait la fonction plus générique en lui donnant un paramètre base, par défaut 5.

+1

Si seulement des entiers et arrondis vers le bas, alors vous pouvez juste faire 'x // base * base' – Tjorriemorrie

+1

c'est moi étant paranoïaque mais je préfère utiliser' floor() 'et' ceil() 'plutôt que de lancer: 'base * floor (x/base)' – user666412

18

Il est juste une question de mise à l'échelle

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

round (x [, n]): les valeurs sont arrondies au multiple le plus proche de 10 à la puissance moins n. Donc, si n est négatif ...

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

Depuis 10 = 5 * 2, vous pouvez utiliser la division entière et multiplication par 2, plutôt que la division flottante et multiplication par 5,0. Non pas que cela ait beaucoup d'importance, à moins que vous aimez décalage de bits

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

+1 pour nous montrer que round() peut gérer des arrondis à des multiples autres que 1.0, y compris des valeurs plus élevées. (Notez, cependant, que l'approche de changement de bit ne fonctionnera pas avec les flottants, sans compter qu'elle est beaucoup moins lisible par la plupart des programmeurs.) –

+1

@Peter Hansen merci pour le +1.Besoin d'avoir un int (x) pour que le bit change pour fonctionner avec des flotteurs. D'accord pas le plus lisible et je ne voudrais pas l'utiliser moi-même, mais j'ai aimé la «pureté» de celui-ci impliquant seulement 1 et non 2 ou 5. – pwdyson

0

Qu'en est-ce:

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

Merde, ce n'était pas la question ... mais je l'ai modifié (voir la version modifiée!). –

+0

Qu'est-ce que divmod? –

3

Version modifiée de divround :-)

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

alors dans ce cas vous utilisez divround (valeur, 5, 3)? ou peut-être diviser (valeur, 5, 2.5)? – pwdyson

+0

divround (valeur, 5, 3), exactement. –

10

Retrait du 'repos' fonctionnerait :

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

Si la valeur est aready un nombre entier:

rounded = val - val % 5 

En fonction:

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

Cela ne fonctionne que pour arrondir vers le bas. – Craig

+0

J'aime cette réponse pour arrondir à la valeur fractionnaire la plus proche. c'est-à-dire si je veux seulement des incréments de 0,25. –

23

Pour arrondir à des valeurs non entières, telles que 0,05:

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

I trouvée utile puisque je pourrait simplement faire une recherche et remplacer dans mon code pour changer "round (" à "myround (", sans avoir à changer les valeurs des paramètres.

-3

Vous pouvez « truc » en int() l'arrondissement au lieu d'arrondir vers le bas en ajoutant 0.5 au nombre vous passez à int().

+1

Cela ne répond pas réellement à la question –

3

Désolé, je voulais commenter la réponse de Alok Singhai, mais il ne me laisse pas en raison d'un manque de réputation =/

Quoi qu'il en soit, nous pouvons généraliser une étape supplémentaire et aller:

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

Cela nous permet d'utiliser des bases non entières, comme .25 ou toute autre base fractionnaire.

2

Je me rends compte que je suis en retard à la fête, mais il semble que cette solution n'a pas été mentionné:

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

... 

Il n'utilise pas la multiplication et ne convertit pas de/vers flotteurs.

Arrondi au plus proche multiple de 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 

Comme vous pouvez le voir, il fonctionne aussi bien pour les nombres négatifs et positifs. Les liens (par exemple -15 et 15) seront toujours arrondis vers le haut.

exemple similaire qui arrondit pas le plus proche multiple de 5, ce qui démontre qu'il se comporte également comme prévu pour une "base" différente:

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

** multiple de 5 **

51 considèrent nécessaire de convertir à 55

code here 

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

Est-ce une réponse ou une autre question? –

1

Dans le cas où quelqu'un a besoin « arrondi financier » (0,5 tours toujours):

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')))) 

Selon la documentation d'autres options d'arrondi sont:

ROUND_CEILING (vers l'infini),
ROUND_DOWN (vers zéro),
ROUND_FLOOR (vers -Infinity),
ROUND_HALF_DOWN (au plus proche avec des liens allant vers zéro),
ROUND_HALF_EVEN (au plus proche avec des liens allant à l'entier pair le plus proche),
ROUND_HALF_UP (t o le plus proche avec des liens s'éloignant de zéro), ou
ROUND_UP (loin de zéro).
ROUND_05UP (loin de zéro si le dernier chiffre après avoir arrondi vers zéro aurait été 0 ou 5, sinon vers zéro)

Par défaut Python utilise ROUND_HALF_EVEN comme il a des avantages statistiques (les résultats arrondis ne sont pas biaisées) .

Questions connexes