J'ai découvert l' //
opérateur en Python qui, dans Python 3, effectue une division avec le sol.
Y a-t-il un opérateur qui divise avec ceil? (Je connais l' /
opérateur qui en Python 3 effectue la division en virgule flottante.)
J'ai découvert l' //
opérateur en Python qui, dans Python 3, effectue une division avec le sol.
Y a-t-il un opérateur qui divise avec ceil? (Je connais l' /
opérateur qui en Python 3 effectue la division en virgule flottante.)
Réponses:
Il n'y a pas d'opérateur qui divise avec ceil. Vous devez import math
et utilisermath.ceil
Vous pouvez simplement faire la division du sol à l'envers:
def ceildiv(a, b):
return -(-a // b)
Cela fonctionne parce que l'opérateur de division de Python effectue la division par étage (contrairement à C, où la division entière tronque la partie fractionnaire).
Cela fonctionne également avec les grands entiers de Python, car il n'y a pas de conversion en virgule flottante (avec perte).
Voici une démonstration:
>>> 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
contrairement à Python (enfin, pas de valeurs significatives; sur Python 64 bits, vous êtes limité aux 30 * (2**63 - 1)
nombres de bits), et même la conversion temporaire en float
peut perdre des informations. Comparez math.ceil((1 << 128) / 10)
avec -(-(1 << 128) // 10)
.
Vous pouvez le faire (x + (d-1)) // d
lors de la division x
par d
, c'est-à-dire (x + 4) // 5
.
math.ceil()
.
sys.float_info.max
- dessus , et qu'il ne nécessite pas d'importation.
def ceiling_division(n, d):
return -(n // -d)
Réminiscence de l' astuce de lévitation de Penn & Teller , cela "bouleverse le monde (avec négation), utilise la division du sol simple (où le plafond et le sol ont été échangés), puis retourne le monde à droite (avec négation à nouveau) "
def ceiling_division(n, d):
q, r = divmod(n, d)
return q + bool(r)
La fonction divmod () donne (a // b, a % b)
des nombres entiers (cela peut être moins fiable avec des flottants en raison d'une erreur d'arrondi). Le pas avec bool(r)
ajoute un au quotient chaque fois qu'il y a un reste non nul.
def ceiling_division(n, d):
return (n + d - 1) // d
Traduisez le numérateur vers le haut pour que la division de plancher s'arrondisse au plafond prévu. Notez que cela ne fonctionne que pour les entiers.
def ceiling_division(n, d):
return math.ceil(n / d)
Le code math.ceil () est facile à comprendre, mais il se convertit des ints en floats et inversement. Ce n'est pas très rapide et cela peut avoir des problèmes d'arrondi. De plus, il s'appuie sur la sémantique Python 3 où "true division" produit un float et où la fonction ceil () renvoie un entier.
-(-a // b)
o_O
-(a // -b)
c'est plus rapide que -(-a // b)
, du moins lors du chronométrage des exemples de jouets avecpython -m timeit ...
Vous pouvez toujours le faire en ligne aussi
((foo - 1) // bar) + 1
En python3, c'est juste un ordre de grandeur plus rapide que de forcer la division float et d'appeler ceil (), à condition que vous vous souciez de la vitesse. Ce que vous ne devriez pas, à moins que vous n'ayez prouvé par l'utilisation que vous en avez besoin.
>>> 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
). Par appel unique, la différence est assez insignifiante.
foo = -8
et bar = -4
, par exemple, la réponse doit être 2, pas 3, tout comme -8 // -4
. La division de plancher de Python est définie comme "celle de la division mathématique avec la fonction 'plancher' appliquée au résultat" et la division de plafond est la même chose mais avec ceil()
au lieu de floor()
.
Notez que math.ceil est limité à 53 bits de précision. Si vous travaillez avec de grands entiers, vous risquez de ne pas obtenir de résultats exacts.
La bibliothèque gmpy2 fournit unc_div
fonction qui utilise l'arrondi au plafond.
Avis de non-responsabilité: je maintiens gmpy2.
python2 -c 'from math import ceil;assert ceil(11520000000000000102.9)==11520000000000000000'
(ainsi que le remplacement python3
) LES DEUX sontTrue
Solution simple: a // b + 1