Parece que ya debería haber pedido cientos (los juegos de palabras son divertidos =) de veces, pero solo puedo encontrar la función para redondear los flotantes. ¿Cómo puedo redondear un entero, por ejemplo: 130 -> 200
?Python redondea el número entero al siguiente cien
Respuesta
redondeo se realiza normalmente en números de punto flotante, y aquí hay tres funciones básicas que debe saber: round
(redondea al número entero más cercano), math.floor
(siempre redondea hacia abajo) y math.ceil
(siempre redondea).
Pregunta sobre enteros y redondeo a cientos, pero aún podemos usar math.ceil
siempre que sus números sean menores que 2 . Para utilizar math.ceil
, simplemente dividimos por 100 en primer lugar, reunir, y se multiplican con 100 después:
>>> import math
>>> def roundup(x):
... return int(math.ceil(x/100.0)) * 100
...
>>> roundup(100)
100
>>> roundup(101)
200
Dividiendo por 100 primero y multiplicamos con 100 después "cambia" dos cifras decimales a la derecha e izquierda de manera que math.ceil
trabaja en los cientos. Se podría utilizar en lugar de 10**n
100 si desea redondear a decenas (n = 1
), miles (n = 3
), etc.
Una forma alternativa de hacer esto es para evitar los números de punto flotante (que han limitado la precisión) y en su lugar utilizar enteros solamente Los enteros tienen una precisión arbitraria en Python, por lo que le permite redondear números de cualquier tamaño. La regla de redondeo es simple: encontrar el resto después de la división con 100, y añadir 100 menos ese resto si es distinto de cero:
>>> def roundup(x):
... return x if x % 100 == 0 else x + 100 - x % 100
Esto funciona para los números de cualquier tamaño:
>>> roundup(100)
100
>>> roundup(130)
200
>>> roundup(1234567891234567891)
1234567891234567900L
I hizo un mini-punto de referencia 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ápido por un factor de dos en comparación con la solución math.ceil
.
Thomas propuso una solución basada en enteros que es idéntica a la que tengo arriba, excepto que usa un truco multiplicando los valores booleanos. Es interesante ver que no hay ninguna ventaja de la velocidad de 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, también quisiera señalar, que si hubiera querido redondear 101-149 de 100 y alrededor de 150 -199 a 200, por ejemplo, Y vuelta a la más cercana cien, a continuación, la incorporada en round
función puede hacer eso por usted:
>>> int(round(130, -2))
100
>>> int(round(170, -2))
200
No estoy haciendo un redondeo normal aquí, si fuera sí, usaría round() – ofko
@ofko: derecho, quieres redondear. El 'math.ceil' es la forma canónica de hacerlo: dividir y multiplicar por 100 es la manera canónica de hacer que 'round', 'ceil' y' floor' funcionen en cientos. –
Después de las ediciones recientes, ahora tiene sentido aceptar esta respuesta. – ofko
Prueba esto:
int(round(130 + 49, -2))
Si su int x es: x + 100 - x % 100
Sin embargo, como se ha señalado en los comentarios, esto devolverá 200 si x==100
.
Si este no es el comportamiento esperado, puede utilizar x + 100*(x%100>0) - x%100
¿Qué pasa si 'x' ya es un múltiplo de 100? –
Es posible que desee utilizar las otras soluciones si no le gustan los números mágicos. Si le preocupa el rendimiento, esto sin embargo se ejecuta más rápido. –
@LukeWoodward Gran punto, voy a editar –
Aquí está una manera general de redondeo al múltiplo más cercano de cualquier número entero positivo:
def roundUpToMultiple(number, multiple):
num = number + (multiple - 1)
return num - (num % multiple)
uso
muestra:
>>> roundUpToMultiple(101, 100) 200 >>> roundUpToMultiple(654, 321) 963
demasiado complicado –
método equivalente, más corto: 'número lambda, múltiple: múltiple * (1 + (número - 1) // múltiple)' –
Para a
no negativo, b
posi tiva, ambos enteros:
>>> rup = lambda a, b: (a + b - 1) // b * b
>>> [(x, rup(x, 100)) for x in (199, 200, 201)]
[(199, 200), (200, 200), (201, 300)]
actualizacióncae la respuesta aceptada actualmente-aparte con números enteros tales que flotador (x)/flotador (y) no puede representarse con precisión como una float
. Ver este código:
import math
def geisler(x, y): return int(math.ceil(x/float(y))) * y
def orozco(x, y): return x + y * (x % y > 0) - x % y
def machin(x, y): return (x + y - 1) // y * y
for m, n in (
(123456789123456789, 100),
(1234567891234567891, 100),
(12345678912345678912, 100),
):
print; print m, "m"; print n, "n"
for func in (geissler, orozco, machin):
print func(m, n), func.__name__
de salida:
123456789123456789 m
100 n
123456789123456800 geisler
123456789123456800 orozco
123456789123456800 machin
1234567891234567891 m
100 n
1234567891234568000 geisler <<<=== wrong
1234567891234567900 orozco
1234567891234567900 machin
12345678912345678912 m
100 n
12345678912345680000 geisler <<<=== wrong
12345678912345679000 orozco
12345678912345679000 machin
y aquí están algunos tiempos:
>\python27\python -m timeit -s "import math;x =130" "int(math.ceil(x/100.0))*100"
1000000 loops, best of 3: 0.342 usec per loop
>\python27\python -m timeit -s "x = 130" "x + 100 * (x % 100 > 0) - x % 100"
10000000 loops, best of 3: 0.151 usec per loop
>\python27\python -m timeit -s "x = 100" "(x + 99) // 100 * 100"
10000000 loops, best of 3: 0.0903 usec per loop
'Sé que el OP se trataba de redondear un número entero' - pero quería señalar que Intentarías usar esas 3 opciones en (0.5,10) que esperaría que regresas 10, luego los primeros dos métodos (geisler y orozco) devuelven 10 como se esperaba, mientras machin devuelve 0 – epeleg
Ésta es una respuesta tardía, pero no 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 prefiere, x + (-x) % 100
).
>>> x = 130
>>> x -= x % -100 # Round x up to next multiple of 100.
>>> x
200
Esto es rápido y sencillo, da resultados correctos para cualquier entero x
(como la respuesta de John Machin) y también da resultados razonables-ish (módulo las advertencias habituales acerca de 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
tu solución es tan rápida como la notación de Martin es más corto Gracias. % timeit 'x = 110' 'x - = x% -100' # 100000000 bucles, mejor de 3: 9.37 ns por ciclo VS % timeit 'x = 110' 'x + 100 * (x% 100> 0) - x% 100 ' # 100000000 bucles, lo mejor de 3: 9.38 ns por ciclo – tagoma
Prueba esto: el uso
import math
def ceilm(number,multiple):
'''Returns a float rounded up by a factor of the multiple specified'''
return math.ceil(float(number)/multiple)*multiple
muestra:
>>> ceilm(257,5)
260
>>> ceilm(260,5)
260
Advertencia: optimizaciones prematuros por delante ...
Dado que muchas de las respuestas aquí hacer la sincronización de esto quería agregar otra alternativa.
Tomando @ Martin Geisler 's
def roundup(x):
return x if x % 100 == 0 else x + 100 - x % 100
(que me gusta mejor por varias razones)
pero factorizar la acción%
def roundup2(x):
x100= x % 100
return x if x100 == 0 else x + 100 - x100
produce una mejora de la velocidad ~ 20% sobre el original
def roundup3(x):
x100 = x % 100
return x if not x100 else x + 100 - x100
Es aún mejor y es ~ 36% más rápido que el original
finalmente estaba pensando que podía dejar caer el operador not
y cambiar el orden de las ramas esperando que esto también aumentara la velocidad pero me desconcerté al descubrir que en realidad, es más lento y cae solo un 23% más rápido que el original.
def roundup4(x):
x100 = x % 100
return x + 100 - x100 if x100 else x
>python -m timeit -s "x = 130" "x if x % 100 == 0 else x + 100 - x % 100"
1000000 loops, best of 3: 0.359 usec per loop
>python -m timeit -s "x = 130" "x100 = x % 100" "x if x100 == 0 else x + 100 - x100"
1000000 loops, best of 3: 0.287 usec per loop
>python -m timeit -s "x = 130" "x100 = x % 100" "x if not x100 else x + 100 - x100"
1000000 loops, best of 3: 0.23 usec per loop
>python -m timeit -s "x = 130" "x100 = x % 100" "x + 100 - x100 if x100 else x"
1000000 loops, best of 3: 0.277 usec per loop
explicaciones sobre por qué 3 es más rápido que 4 sería muy bienvenido.
- 1. Redondea al entero más cercano
- 2. Python: Redondo al siguiente número entero predefinido en la lista
- 3. ¿Cómo puedo redondear números al siguiente medio entero?
- 4. Cadena binaria al número entero
- 5. Clase Python con emulación de número entero
- 6. Math redondo para siempre número entero superior
- 7. redondear un número de coma flotante al siguiente valor entero en java
- 8. ¿Por qué mi número se redondea incorrectamente?
- 9. Python número entero de incremento ++ con
- 10. ¿Redondea al décimo más cercano?
- 11. Powershell - Redondee al número entero más cercano
- 12. número entero Divide y obtener valor entero
- 13. conseguir siguiente entero disponible utilizando LINQ
- 14. número entero no 'se reduce a un número entero'
- 15. Reinterpretar el número de coma flotante al entero
- 16. /euclidiana número entero división de la división
- 17. Redondear un flotante hasta el siguiente entero en javascript
- 18. Número entero o número decimal
- 19. ¿Cómo encuentro el siguiente múltiplo de 10 de cualquier número entero?
- 20. Adición de un número entero a un flotador en PHP redondea el flotador a lugar 1 decimal
- 21. Inversión de bits del número entero de Python
- 22. Truncar/redondear el número entero en JavaScript?
- 23. Python: prueba si un argumento es un número entero
- 24. máximo número entero corto con signo en Python
- 25. número entero en javascript?
- 26. php validar número entero
- 27. ¿Cubre el número de Python?
- 28. PreferenceActivity: guardar el valor como número entero
- 29. Fecha y hora en el número entero
- 30. VBA Fecha como número entero
¿Desea que 100 se redondeen hasta 200 también? – DSM
No, la respuesta de Thomas hace justo lo que necesito – ofko
La respuesta de Thomas * hace * alrededor de 100 hasta 200. Por eso pregunté. – DSM