2013-02-11 29 views
59

Python 3'ün kat ile bölümü olan Python'daki // operatörünü öğrendim.Python'da // operatörü tavan karşılığı var mı?

Bunun yerine tavanı bölen bir operatör var mı? (Python 3'te kayan nokta bölümlemesi yapan / işlecini biliyorum.)

+0

"böl-sonra-ceil" gerçekten matematikte ortak bir şey değildir:

İşte gösteri bu. – millimoose

+0

Önemli: int veya float sonucunu ister misiniz? – smci

+3

Dlitz'e kabul edilen cevabı değiştirmelisiniz. math.ceil şamandıralar içindir, Python'un keyfi hassasiyetli uzun kuyruklarıyla çalışmaz. – endolith

cevap

35

Tavan ile ayrılan bir operatör yok. yani (x + 4) // 5, d tarafından x bölünmesi zaman import math gerekiyor ve math.ceil

+0

böylece foobar = math.ceil (foo/bar)? Hmm, bununla yaşayabilirim, kullanmak istediğim her şeyi bilmiyorum, sadece merak ettim, teşekkürler – Cradam

+8

–1 ** kullanmayın **, bu çok büyük tamsayılar için başarısız olmaya başlayacaktır. Birden çok kesinlikli aritmetik kitaplık kullanın ya da [this] (https://stackoverflow.com/a/17511341/674039) yaklaşımıyla tamsayı alanında kalın. – wim

9

Sen (x + (d-1)) // d yapabileceğini kullanın. Sadece python3 olarak satır içi hem

((foo - 1) // bar) + 1 

bunu hep yapabilirsiniz

+0

Sonsuza dek kullandığım klasik yöntem bu. Olsa da negatif bölenler için işe yaramıyor. –

+0

[Aynı sonuç] (https://repl.it/FZGd/5) 'math.ceil() 'olarak üretilir. – Abhijeet

+0

@Abhijeet Evet, soru sorar. Bunun dışında, sys.float_info.max' üzerindeki büyük tamsayılar için daha iyi çalışır ve bir içe aktarma gerektirmez. – Artyer

8

, bu hıza önem İşletmesi, daha hızlı şamandıra bölümü zorlayarak ve) (hücrelerinin, çağırmaktan daha büyüklükte bir düzenin sadece utangaç . İhtiyacınız olan kullanımla kanıtlanmadıkça, hangisini 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 
+0

Bu testleri kendim yaptım sadece yaklaşık 12.5 saniye, ehrm, neden bu kadar büyük bir hız farkı olduğunda hızı umursamıyorum? – Cradam

+2

@Cradam 100 milyon çağrı yapıyor olduğunu unutmayın ('number = 100000000'). Tek bir çağrı başına, fark oldukça önemsizdir. –

+0

ahh, teşekkürler, ceil yöntemini kullanıyorum o zaman – Cradam

7

math.ceil'in 53 bit hassasiyetle sınırlı olduğunu unutmayın. Büyük tamsayılarla çalışıyorsanız, kesin sonuç alamazsınız.

gmpy2 libary, tavan yuvarlama kullanan c_div işlevini sağlar.

Yasal Uyarı: Gmpy2'yi koruyorum.

+2

Bu paket oldukça yoğun bir matematik ya da bilim odaklı bir şey yapıyor olsaydı faydalı olurdu, ancak çekirdek kütüphaneleri kullanan cevabı tercih ederim. Olumlu bir cevap olduğu için bir vesile veriyorum – Cradam

163

Sen sadece yapabilirsiniz baş aşağı kat bölümü:

def ceildiv(a, b): 
    return -(-a // b) 

Bu çalıştığı için Python's division operator does floor division (tamsayı bölme kesir kısmını C, aksine).

Bu, Python'un büyük tamsayılarıyla da çalışır, çünkü (kayıplı) kayan nokta dönüşümü yoktur. `//` tamsayı bölme-ile-modülü operasyon dayalı iken,

>>> 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] 
+11

Vay! Çok zeki! Bu kabul edilen çözüm olmalı. – apadana

İlgili konular