Solución:
El redondeo generalmente se realiza en números de punto flotante, y aquí hay tres funciones básicas que debe conocer: round
(redondea al número entero más cercano), math.floor
(siempre redondea hacia abajo), y math.ceil
(siempre redondea hacia arriba).
Preguntas sobre números enteros y redondeo a cientos, pero aún podemos usar math.ceil
siempre que sus números sean menores a 253. Usar math.ceil
, primero dividimos por 100, redondeamos hacia arriba y luego multiplicamos por 100:
>>> import math
>>> def roundup(x):
... return int(math.ceil(x / 100.0)) * 100
...
>>> roundup(100)
100
>>> roundup(101)
200
Dividir por 100 primero y luego multiplicar por 100 “desplaza” dos lugares decimales a la derecha y a la izquierda para que math.ceil
funciona en los cientos. Podrías usar 10**n
en lugar de 100 si desea redondear a decenas (n = 1
), miles (n = 3
), etc.
Una forma alternativa de hacer esto es evitar los números de punto flotante (tienen una precisión limitada) y, en su lugar, usar solo números enteros. Los enteros tienen precisión arbitraria en Python, por lo que esto le permite redondear números de cualquier tamaño. La regla para redondear es simple: encuentre el resto después de la división con 100 y agregue 100 menos este resto si no es cero:
>>> def roundup(x):
... return x if x % 100 == 0 else x + 100 - x % 100
Esto funciona para números de cualquier tamaño:
>>> roundup(100)
100
>>> roundup(130)
200
>>> roundup(1234567891234567891)
1234567891234567900L
Hice un mini-benchmark de las dos soluciones:
$ python -m timeit -s 'import math' -s 'x = 130' 'int(math.ceil(x/100.0)) * 100'
1000000 loops, best of 3: 0.364 usec per loop
$ python -m timeit -s 'x = 130' 'x if x % 100 == 0 else x + 100 - x % 100'
10000000 loops, best of 3: 0.162 usec per loop
La solución entera pura es más rápida por un factor de dos en comparación con la math.ceil
solución.
Thomas propuso una solución basada en números enteros que es idéntica a la que tengo arriba, excepto que usa un truco al multiplicar valores booleanos. Es interesante ver que no existe una ventaja de velocidad al escribir el código de esta manera:
$ python -m timeit -s 'x = 130' 'x + 100*(x%100>0) - x%100'
10000000 loops, best of 3: 0.167 usec per loop
Como observación final, permítame también señalar que si hubiera querido redondear 101-149 a 100 y redondear 150-199 a 200, por ejemplo, redondear a la más cercano cien, luego el incorporado round
La función puede hacer eso por ti:
>>> int(round(130, -2))
100
>>> int(round(170, -2))
200
Esta es una respuesta tardía, pero hay una solución simple que combina los mejores aspectos de las respuestas existentes: el siguiente múltiplo de 100
desde x
es x - x % -100
(o si lo prefieres, x + (-x) % 100
).
>>> x = 130
>>> x -= x % -100 # Round x up to next multiple of 100.
>>> x
200
Esto es rápido y simple, da resultados correctos para cualquier número entero. x
(como la respuesta de John Machin) y también da resultados razonables (módulo las advertencias habituales sobre la representación de punto flotante) si x
es un flotador (como la respuesta de Martin Geisler).
>>> x = 0.1
>>> x -= x % -100
>>> x
100.0
Prueba esto:
int(round(130 + 49, -2))