Me enteré del //
operador en Python que en Python 3 hace división con piso.
¿Existe un operador que divide con ceil en su lugar? (Sé sobre el /
operador que en Python 3 hace la división de punto flotante).
Me enteré del //
operador en Python que en Python 3 hace división con piso.
¿Existe un operador que divide con ceil en su lugar? (Sé sobre el /
operador que en Python 3 hace la división de punto flotante).
Respuestas:
No hay operador que divida con ceil. Necesitas import math
y usamath.ceil
Puede hacer la división del piso al revés:
def ceildiv(a, b):
return -(-a // b)
Esto funciona porque el operador de división de Python realiza la división de piso (a diferencia de C, donde la división de enteros trunca la parte fraccionaria).
Esto también funciona con los grandes enteros de Python, porque no hay conversión de punto flotante (con pérdida).
He aquí una demostración:
>>> from __future__ import division # a/b is float division
>>> from math import ceil
>>> b = 3
>>> for a in range(-7, 8):
... print(["%d/%d" % (a, b), int(ceil(a / b)), -(-a // b)])
...
['-7/3', -2, -2]
['-6/3', -2, -2]
['-5/3', -1, -1]
['-4/3', -1, -1]
['-3/3', -1, -1]
['-2/3', 0, 0]
['-1/3', 0, 0]
['0/3', 0, 0]
['1/3', 1, 1]
['2/3', 1, 1]
['3/3', 1, 1]
['4/3', 2, 2]
['5/3', 2, 2]
['6/3', 2, 2]
['7/3', 3, 3]
int
no las tiene (bueno, no significativas; en Python de 64 bits está limitado a 30 * (2**63 - 1)
números de bits), e incluso convertir temporalmente a float
puede perder información. Comparar math.ceil((1 << 128) / 10)
con -(-(1 << 128) // 10)
.
Podrías hacer (x + (d-1)) // d
al dividir x
por d
, es decir (x + 4) // 5
.
math.ceil()
.
sys.float_info.max
y no requiere una importación.
def ceiling_division(n, d):
return -(n // -d)
Con reminiscencias del truco de levitación de Penn & Teller , esto "pone el mundo patas arriba (con negación), utiliza una división de piso simple (donde el techo y el piso se han intercambiado) y luego gira el mundo hacia arriba (con la negación nuevamente) "
def ceiling_division(n, d):
q, r = divmod(n, d)
return q + bool(r)
La función divmod () proporciona (a // b, a % b)
números enteros (esto puede ser menos confiable con flotantes debido a un error de redondeo). El paso con bool(r)
agrega uno al cociente siempre que haya un resto distinto de cero.
def ceiling_division(n, d):
return (n + d - 1) // d
Traslade el numerador hacia arriba para que la división del piso se redondee hacia abajo hasta el techo previsto. Tenga en cuenta que esto solo funciona para números enteros.
def ceiling_division(n, d):
return math.ceil(n / d)
El código math.ceil () es fácil de entender, pero se convierte de ints a floats y viceversa. Esto no es muy rápido y puede tener problemas de redondeo. Además, se basa en la semántica de Python 3 donde la "división verdadera" produce un flotador y donde la función ceil () devuelve un número entero.
-(-a // b)
o_O
-(a // -b)
es más rápido que -(-a // b)
, al menos cuando ejemplos de juguete con el tiempopython -m timeit ...
Siempre puedes hacerlo en línea también
((foo - 1) // bar) + 1
En python3, esto es apenas un orden de magnitud más rápido que forzar la división flotante y llamar a ceil (), siempre que le importe la velocidad. Lo cual no debería, a menos que haya probado a través del uso que lo necesita.
>>> timeit.timeit("((5 - 1) // 4) + 1", number = 100000000)
1.7249219375662506
>>> timeit.timeit("ceil(5/4)", setup="from math import ceil", number = 100000000)
12.096064013894647
number=100000000
). Por llamada, la diferencia es bastante insignificante.
foo = -8
y bar = -4
, por ejemplo, la respuesta debería ser 2, no 3, como -8 // -4
. La división de piso de Python se define como "la división matemática con la función 'piso' aplicada al resultado" y la división de techo es lo mismo pero con en ceil()
lugar de floor()
.
Tenga en cuenta que math.ceil está limitado a 53 bits de precisión. Si trabaja con números enteros grandes, es posible que no obtenga resultados exactos.
La biblioteca gmpy2 proporciona una c_div
función que utiliza redondeo de techo.
Descargo de responsabilidad: mantengo gmpy2.
python2 -c 'from math import ceil;assert ceil(11520000000000000102.9)==11520000000000000000'
(además de sustituir python3
) AMBOS sonTrue
Solución simple: a // b + 1