क्या पायथन में // ऑपरेटर के बराबर छत है?


127

मुझे //पायथन में ऑपरेटर के बारे में पता चला जो कि पायथन 3 में फर्श के साथ विभाजन करता है।

क्या कोई ऑपरेटर है जो इसके बजाय छत के साथ विभाजित करता है? (मैं उस /ऑपरेटर के बारे में जानता हूं जो पायथन 3 फ्लोटिंग पॉइंट डिवीजन करता है।)


1
महत्वपूर्ण: क्या आप एक इंट या फ्लोट परिणाम चाहते हैं?
एसएमसीआई

10
आपको dlitz का स्वीकृत उत्तर बदलना चाहिए। math.ceil फ़्लोट्स के लिए है, यह पायथन की मनमानी-सटीक लंबी इनट्स के साथ काम नहीं करता है।
'17:

2
@milllimoose यह सवाल वैध है, क्योंकि 1) "छत विभाजन" भी "मापांक के साथ विभाजन" पर आधारित है, 2) गणित वास्तव में यह नहीं कहता है कि क्या आम है और क्या नहीं है, 3) आपको "निरंतर बिन के लिए इस ऑपरेशन की आवश्यकता है पैकिंग की समस्या ", यानी $ k $ के आकार के कितने बक्से $ n $ आइटम पैक करने के लिए तैयार किए गए हैं।
टॉमाज़ गैंडर

जवाबों:


55

कोई भी ऑपरेटर नहीं है जो छत के साथ विभाजित करता है। आपको import mathउपयोग करने की आवश्यकता हैmath.ceil


so foobar = math.ceil (फू / बार)? हम्म, मैं उस के साथ रह सकता हूं, कहीं भी नहीं जानता कि मैं उस का उपयोग करना चाहता था, बस उत्सुक था, धन्यवाद
क्रैडम

37
-1 का उपयोग न करें , यह बहुत बड़े पूर्णांक के लिए विफल होने लगेगा। या तो एकाधिक-सटीक अंकगणित पुस्तकालय का उपयोग करें या इस दृष्टिकोण के साथ पूर्णांक डोमेन में रहें ।
विम

5
पूर्णांक डोमेन में निश्चित रूप से रहें। यह लगभग अधिक प्रदर्शन करने की गारंटी है और सिरदर्द कम है।
सैमी बेनचेरी

1
@ दाविद g वोंग gmpy2 (यहां एक और जवाब में उल्लेख किया गया है) अच्छा है।
विम

1
ध्यान दें कि math.ceil परिशुद्धता के 53 बिट्स तक सीमित है। यदि आप बड़े पूर्णांक के साथ काम कर रहे हैं, तो आपको सटीक परिणाम नहीं मिल सकते हैं।
Techkuz

291

आप बस उल्टा फर्श विभाजन कर सकते हैं:

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

यह काम करता है क्योंकि पायथन का डिवीजन ऑपरेटर फ्लोर डिवीजन करता है (सी के विपरीत, जहां पूर्णांक विभाजन आंशिक भाग को काटता है)।

यह पायथन के बड़े पूर्णांकों के साथ भी काम करता है, क्योंकि फ्लोटिंग-पॉइंट रूपांतरण नहीं है।

यहाँ एक प्रदर्शन है:

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

2
@ प्रपदना मैं मानता हूँ कि यह बहुत स्मार्ट है, लेकिन बहुत पठनीय और बनाए रखने के लिए कठिन नहीं है! मैंने गणित से छत आयात करने का फैसला किया है ताकि जब मेरा कोई साथी मेरे लाइन ऑफ़ कोड को पढ़े तो वह समझ जाए कि वह क्या करता है!
स्लिमकेनी

2
@ प्रपदना मैं असहमत हूँ। सवाल पूछा गया कि क्या "पायथन" में "इसके लिए एक ऑपरेटर" है। प्रतिक्रियाओं के आधार पर, उत्तर "नहीं" प्रतीत होता है। मैं इसकी उपयोगिता के लिए dlitz के उत्तर को बढ़ा रहा हूं, हालांकि।
एना निंबस

12
@SlimCheney इस विधि को एक प्रलेखित फ़ंक्शन में ले जाएँ और आप जाने के लिए अच्छे हैं। एक व्यापक गति में प्रदर्शन + पठनीयता।
सैमी बेनचेरी

2
@SamyBencherif: न केवल प्रदर्शन + पठनीयता, बल्कि बड़े इनपुट के लिए शुद्धता भी; फ्लोटिंग पॉइंट की प्रतिनिधित्व सीमाएँ हैं, जबकि पायथन के int(अच्छी तरह से, कोई सार्थक नहीं हैं; 64 बिट पायथन पर आप 30 * (2**63 - 1)बिट संख्या तक सीमित हैं ), और यहां तक ​​कि अस्थायी रूप से परिवर्तित करने floatसे जानकारी खो सकती है। से तुलना math.ceil((1 << 128) / 10)करें -(-(1 << 128) // 10)
शैडो रेंजर

1
यह सिर्फ में मानक पुस्तकालय शामिल किया जाना चाहिए
endolith

26

तुम कर सकते हो (x + (d-1)) // dजब विभाजित xद्वारा d, यानी (x + 4) // 5


2
यह क्लासिक विधि है जो मैंने हमेशा के लिए उपयोग की है। हालांकि नकारात्मक विभाजकों के लिए काम नहीं करता है।
रैनसम

यह उसी के रूप में परिणाम उत्पन्न करता है math.ceil()
अभिजीत ३०'१

3
@ अभिजीत हां, यही सवाल पूछता है। सिवाय इसके ऊपर के बड़े पूर्णांकों के लिए बेहतर काम करता है sys.float_info.max, और इसके लिए आयात की आवश्यकता नहीं होती है।
१०'१

22

समाधान 1: फर्श को छत के साथ नकार में बदलें

def ceiling_division(n, d):
    return -(n // -d)

पेन एंड टेलर लेविटेशन ट्रिक की याद दिलाता है , यह "दुनिया को उल्टा कर देता है (नकारात्मकता के साथ), सादे फर्श विभाजन (जहां छत और फर्श की अदला-बदली हुई है) का उपयोग करता है, और फिर दुनिया को राइट-साइड अप (फिर से नकारात्मकता) के साथ बदल देता है "

समाधान 2: Divmod () को कार्य करने दें

def ceiling_division(n, d):
    q, r = divmod(n, d)
    return q + bool(r)

Divmod () समारोह देता (a // b, a % b)पूर्णांकों के लिए (इस दौर बंद त्रुटि के कारण तैरता साथ कम विश्वसनीय हो सकती)। bool(r)जब भी कोई शून्य शून्य शेष रहता है, तो चरण एक को भागफल में जोड़ता है।

समाधान 3: विभाजन से पहले अंश को समायोजित करें

def ceiling_division(n, d):
    return (n + d - 1) // d

अंश का ऊपर की ओर अनुवाद करें ताकि मंजिल विभाजन गोल छत के नीचे आ जाए। ध्यान दें, यह केवल पूर्णांकों के लिए काम करता है।

समाधान 4: math.ceil () का उपयोग करने के लिए फ़्लोट में कनवर्ट करें

def ceiling_division(n, d):
    return math.ceil(n / d)

Math.ceil () कोड समझने में आसान है, लेकिन यह तैरता और वापस करने के लिए ints से बदल देता है। यह बहुत तेज़ नहीं है और इसमें समस्याएँ हो सकती हैं। इसके अलावा, यह पायथन 3 शब्दार्थ पर निर्भर करता है जहां "सच्चा विभाजन" एक फ्लोट का उत्पादन करता है और जहां छत () फ़ंक्शन एक पूर्णांक देता है।


2
त्वरित परीक्षण में, # 1 सबसे तेजी से यहाँ, है भी की तुलना में -(-a // b)o_O
endolith

यहाँ इसकी पुष्टि की जाती है कि टॉय टाइम कम से कम होता -(a // -b)है -(-a // b), जब खिलौना उदाहरण मिलता हैpython -m timeit ...
जशा

19

आप हमेशा इसे केवल इनलाइन भी कर सकते हैं

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

Python3 में, यह फ्लोट डिवीजन को मजबूर करने और सीलिंग () को कॉल करने की तुलना में तेज़ी के एक आदेश से शर्मीली है, बशर्ते आपको गति के बारे में परवाह हो। जब तक आपको उस उपयोग के माध्यम से साबित नहीं करना चाहिए, जिसकी आपको आवश्यकता है।

>>> timeit.timeit("((5 - 1) // 4) + 1", number = 100000000)
1.7249219375662506
>>> timeit.timeit("ceil(5/4)", setup="from math import ceil", number = 100000000)
12.096064013894647

बस उन परीक्षणों को मैंने स्वयं चलाया, जिनके बारे में मुझे 12.5 सेकंड मिलते हैं, अहं, मैं इतनी बड़ी गति के अंतर के कारण गति की परवाह क्यों नहीं करूंगा?
Cradam

3
@Cradam ध्यान दें कि वह 100 मिलियन कॉल ( number=100000000) कर रहा है। एकल कॉल के अनुसार, अंतर बहुत ही महत्वहीन है।
रशी पांचाल

4
क्योंकि कोड स्पष्टता सभी को ट्रम्प करती है। शायद इस मामले में स्पष्टता स्पष्ट है। लेकिन आपको हमेशा पहले पठनीय / अनुरक्षण योग्य बनाना चाहिए। कब, और केवल कब, आपने एक प्रदर्शन चौकी की खोज की है, क्या आप नियम तोड़ते हैं। आधुनिक मशीनें बहुत तेज हैं, और इसलिए अक्सर आपके अन्य सामान के सभी कार्यक्रम शोर में खो जाने वाले इस तरह के अंतर को प्रस्तुत कर रहे हैं।
ट्रैविस ग्रिग्स

6
@ TravisGriggs फ़्लोटिंग पॉइंट गणित के बजाय पूर्णांक गणित का उपयोग करते हुए गति के लिए नहीं है। बड़े पर्याप्त पूर्णांकों के लिए फ्लोट गणित गलत उत्तर देता है
एंडोलिथ

1
तो foo = -8और bar = -4, उदाहरण के लिए, इस सवाल का जवाब 2, नहीं 3, बस की तरह होना चाहिए -8 // -4। पायथन फ्लोर डिवीजन को " फर्श के गणितीय गणित के रूप में परिभाषित किया गया है, जिसके परिणाम में 'फ्लोर' फ़ंक्शन लागू होता है" और सीलिंग डिवीजन एक ही बात है, लेकिन ceil()इसके बजाय floor()
एंडोलिथ

8

ध्यान दें कि math.ceil परिशुद्धता के 53 बिट्स तक सीमित है। यदि आप बड़े पूर्णांक के साथ काम कर रहे हैं, तो आपको सटीक परिणाम नहीं मिल सकते हैं।

Gmpy2 पुस्तकालय प्रदान करता है एकc_div समारोह जो छत राउंडिंग उपयोग करता है।

अस्वीकरण: मैं gmpy2 बनाए रखता हूं।


3
यह पैकेज उपयोगी होगा अगर मैं कुछ भारी गणित या विज्ञान केंद्रित कर रहा था, मैं उस उत्तर को पसंद करता हूं जो कोर लाइब्रेरी का उपयोग करता है। मैं एक उत्थान दे रहा हूं, हालांकि यह एक उपयोगी उत्तर है
क्रादम १२'१३

वाह, पुष्टि कर सकते हैं। python2 -c 'from math import ceil;assert ceil(11520000000000000102.9)==11520000000000000000'(साथ ही प्रतिस्थापित python3) BOTH हैंTrue
JamesTheAwesomeDude

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.