//
Python'daki operatörü Python 3'te yerle bölme yapan Python'da öğrendim .
Bunun yerine tavanla bölünen bir operatör var mı? ( /
Python 3'te kayan nokta bölme yapan operatörü biliyorum .)
//
Python'daki operatörü Python 3'te yerle bölme yapan Python'da öğrendim .
Bunun yerine tavanla bölünen bir operatör var mı? ( /
Python 3'te kayan nokta bölme yapan operatörü biliyorum .)
Yanıtlar:
Tavana bölünen operatör yoktur. İhtiyacın var import math
ve kullanmalısınmath.ceil
Sadece baş aşağı kat bölme yapabilirsiniz:
def ceildiv(a, b):
return -(-a // b)
Bu işe yarar çünkü Python'un bölme operatörü kat bölme yapar (tamsayı bölmenin kesirli bölümü kestiği C'nin aksine).
Bu aynı zamanda Python'un büyük tam sayılarıyla da çalışır, çünkü (kayıplı) kayan nokta dönüşümü yoktur.
İşte bir gösteri:
>>> 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
sahip olmadığı (iyi, anlamlı olanları yok; 64 bit Python'da 30 * (2**63 - 1)
bit sayılarıyla sınırlısınız) ve hatta geçici olarak dönüştürmek float
bilgi kaybedebilir. Karşılaştırma math.ceil((1 << 128) / 10)
için -(-(1 << 128) // 10)
.
Sen yapabileceğini (x + (d-1)) // d
bölünürken, x
tarafından d
yani (x + 4) // 5
.
math.ceil()
.
sys.float_info.max
ve içe aktarma gerektirmez.
def ceiling_division(n, d):
return -(n // -d)
Penn & Teller havaya yükselme hilesini anımsatan bu "dünyayı ters çevirir (olumsuzlukla), düz zemin bölmesini kullanır (tavan ve zeminin değiştirildiği yerde) ve sonra dünyayı sağ tarafa çevirir (tekrar olumsuzla) "
def ceiling_division(n, d):
q, r = divmod(n, d)
return q + bool(r)
Divmod () fonksiyonu verir (a // b, a % b)
(bu durum yuvarlama hatası yüzdürücülü az güvenilir olabilir) tamsayılar için. İle adım, bool(r)
sıfır olmayan bir kalan olduğunda bölüme bir ekler.
def ceiling_division(n, d):
return (n + d - 1) // d
Payı yukarı doğru çevirin, böylece kat bölmesi istenen tavana yuvarlanır. Bunun yalnızca tam sayılar için işe yaradığını unutmayın.
def ceiling_division(n, d):
return math.ceil(n / d)
Math.ceil () kodu anlamak kolay, ancak yüzen ve arkaya ints gelen dönüştürür. Bu çok hızlı değil ve yuvarlama sorunları olabilir. Ayrıca, "true division" ın bir float ürettiği ve ceil () fonksiyonunun bir tamsayı döndürdüğü Python 3 semantiğine dayanır .
-(-a // b)
o_O ile karşılaştırıldığında bile en hızlısı
-(a // -b)
daha hızlı-(-a // b)
python -m timeit ...
Her zaman sadece satır içi olarak da yapabilirsiniz
((foo - 1) // bar) + 1
Python3'te, bu, hızı önemsediğiniz sürece float bölümünü zorlamaktan ve ceil () 'i çağırmaktan daha hızlıdır. Gereksinim duyduğunuz kullanım yoluyla kanıtlamadıkça, yapmamalısınız.
>>> 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
). Tek aramada fark oldukça önemsizdir.
foo = -8
ve bar = -4
, örneğin, cevap 3 değil, 2 olmalıdır -8 // -4
. Python taban bölümü, "sonuca uygulanan 'zemin' işlevi ile matematiksel bölme" olarak tanımlanır ve tavan bölme aynı şeydir, ancak ceil()
bunun yerine floor()
.
Math.ceil'in 53 bitlik hassasiyetle sınırlı olduğunu unutmayın. Büyük tam sayılarla çalışıyorsanız, kesin sonuçlar alamayabilirsiniz.
Gmpy2 kitaplığındaki bir sağlar c_div
tavan yuvarlama kullanan işlevi.
Sorumluluk reddi: gmpy2'yi koruyorum.
python2 -c 'from math import ceil;assert ceil(11520000000000000102.9)==11520000000000000000'
(aynı zamanda ikame de python3
)True
Basit çözüm: a // b + 1