Ho scoperto l' //
operatore in Python che in Python 3 fa la divisione con il pavimento.
Esiste invece un operatore che divide con ceil? (Conosco l' /
operatore che in Python 3 esegue la divisione in virgola mobile.)
Ho scoperto l' //
operatore in Python che in Python 3 fa la divisione con il pavimento.
Esiste invece un operatore che divide con ceil? (Conosco l' /
operatore che in Python 3 esegue la divisione in virgola mobile.)
Risposte:
Non c'è operatore che divide con ceil. È necessario import math
e utilizzaremath.ceil
Puoi semplicemente eseguire la divisione del pavimento capovolta:
def ceildiv(a, b):
return -(-a // b)
Questo funziona perché l'operatore di divisione di Python esegue la divisione dei piani (a differenza di C, dove la divisione intera tronca la parte frazionaria).
Funziona anche con i grandi interi di Python, perché non c'è conversione in virgola mobile (con perdita).
Ecco una dimostrazione:
>>> 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 (beh, non significative; su Python a 64 bit sei limitato a 30 * (2**63 - 1)
numeri di bit), e anche la conversione temporanea in float
può perdere informazioni. Confronta math.ceil((1 << 128) / 10)
con -(-(1 << 128) // 10)
.
Potresti fare (x + (d-1)) // d
quando dividi x
per d
, ad es (x + 4) // 5
.
math.ceil()
.
sys.float_info.max
e non richiede un'importazione.
def ceiling_division(n, d):
return -(n // -d)
Ricorda il trucco della levitazione Penn & Teller , questo "capovolge il mondo (con negazione), usa una divisione semplice del pavimento (dove il soffitto e il pavimento sono stati scambiati), e poi gira il mondo sul lato destro (di nuovo con la negazione) "
def ceiling_division(n, d):
q, r = divmod(n, d)
return q + bool(r)
La funzione divmod () fornisce gli (a // b, a % b)
interi (questo potrebbe essere meno affidabile con i float a causa di un errore di arrotondamento). Il passaggio con bool(r)
aggiunge uno al quoziente ogni volta che è presente un resto diverso da zero.
def ceiling_division(n, d):
return (n + d - 1) // d
Traslare il numeratore verso l'alto in modo che la divisione del pavimento si arrotondi per difetto al soffitto previsto. Nota, questo funziona solo per i numeri interi.
def ceiling_division(n, d):
return math.ceil(n / d)
Il codice math.ceil () è facile da capire, ma converte da int a float e viceversa . Non è molto veloce e potrebbe avere problemi di arrotondamento. Inoltre, si basa sulla semantica di Python 3 dove "true division" produce un float e dove la funzione ceil () restituisce un numero intero.
-(-a // b)
o_O
-(a // -b)
è più veloce di -(-a // b)
, almeno quando si temporizzano esempi di giocattoli conpython -m timeit ...
Puoi sempre farlo anche in linea
((foo - 1) // bar) + 1
In python3, questo è appena un ordine di grandezza più veloce che forzare la divisione in virgola mobile e chiamare ceil (), a patto che ti interessi della velocità. Cosa che non dovresti, a meno che tu non abbia dimostrato attraverso l'uso che è necessario.
>>> 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
). Per singola chiamata, la differenza è piuttosto insignificante.
foo = -8
e bar = -4
, ad esempio, la risposta dovrebbe essere 2, non 3, proprio come -8 // -4
. La divisione del pavimento in Python è definita come "quella della divisione matematica con la funzione 'pavimento' applicata al risultato" e la divisione del soffitto è la stessa cosa ma con ceil()
invece di floor()
.
Si noti che math.ceil è limitato a 53 bit di precisione. Se stai lavorando con numeri interi di grandi dimensioni, potresti non ottenere risultati esatti.
La libreria gmpy2 fornisce una c_div
funzione che utilizza l'arrotondamento del soffitto.
Disclaimer: mantengo gmpy2.
python2 -c 'from math import ceil;assert ceil(11520000000000000102.9)==11520000000000000000'
(oltre a sostituire python3
) ENTRAMBI sonoTrue
Soluzione semplice: a // b + 1