redondeo redondear numero multiplicacion flotante entero entera decimales python math

multiplicacion - redondear un numero en python 3



Python redondea un entero hasta el próximo cien (8)

Advertencia: optimizaciones prematuras por delante ...

Dado que muchas de las respuestas aquí hacen el tiempo 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 teniendo en cuenta el% de acción

def roundup2(x): x100= x % 100 return x if x100 == 0 else x + 100 - x100

Otorga una mejora de 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 pensé que podía dejar caer al operador " not y cambiar el orden de las ramas con la esperanza de que esto también aumentara la velocidad, pero me desconcerté al descubrir que en realidad es más lento y es 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

las explicaciones sobre por qué 3 es más rápido que 4 serían bienvenidas.

Parece que ya debería haber pedido cientos (juegos de palabras son divertidos =) de veces, pero solo puedo encontrar la función para redondear carrozas. ¿Cómo puedo redondear un entero, por ejemplo: 130 -> 200 ?


Aquí hay una forma general de redondear al múltiplo más cercano de cualquier entero positivo:

def roundUpToMultiple(number, multiple): num = number + (multiple - 1) return num - (num % multiple)

Uso de muestra:

>>> roundUpToMultiple(101, 100) 200 >>> roundUpToMultiple(654, 321) 963


El redondeo generalmente se realiza en números de coma flotante, y aquí hay tres funciones básicas que debe conocer: round (redondea al entero más cercano), math.floor . math.floor (siempre redondea hacia abajo) y math.ceil ( math.ceil siempre hacia arriba).

Usted pregunta por enteros y redondea cientos, pero aún podemos usar math.ceil siempre que sus números sean menores que 2 53 . Para usar math.ceil , solo dividimos entre 100 primero, redondeo hacia arriba y luego multiplicamos con 100:

>>> import math >>> def roundup(x): ... return int(math.ceil(x / 100.0)) * 100 ... >>> roundup(100) 100 >>> roundup(101) 200

Al dividir por 100 primero y luego multiplicar por 100, "desplaza" dos lugares decimales a la derecha e izquierda para que math.ceil trabaje en los cientos. Puede usar 10**n lugar de 100 si desea redondear a decenas ( n = 1 ), miles ( n = 3 ), etc.

Una forma alternativa de hacerlo es evitar los números de coma flotante (tienen una precisión limitada) y en su lugar usar 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 para el redondeo 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 en 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 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ítanme también señalar que si hubieran querido redondear 101-149 a 100 y redondear 150-199 a 200, por ejemplo, redondear a la centena más cercana , entonces la función de round incorporada puede hacer eso por ustedes :

>>> 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 prefiere, 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 los 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


Para a entero no negativo, b positivo, 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ón La respuesta actualmente aceptada se desmorona con números enteros tales que float (x) / float (y) no se puede representar con precisión como float . Vea 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__

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


Prueba esto:

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

Uso de muestra:

>>> ceilm(257,5) 260 >>> ceilm(260,5) 260


Prueba esto:

int(round(130 + 49, -2))


Si su int es x: x + 100 - x % 100

Sin embargo, como se señaló en los comentarios, esto devolverá 200 si x==100 .

Si este no es el comportamiento esperado, puede usar x + 100*(x%100>0) - x%100