पायथन में नकारात्मक संख्याओं पर मॉडुलो ऑपरेशन


94

मैंने पायथन में नकारात्मक संख्याओं के बारे में कुछ अजीब व्यवहार पाया है:

>>> -5 % 4
3

क्या कोई समझा सकता है कि क्या चल रहा है?


25
मेरे लिए सही लगता
Wheaties

6
..., -9, -5, -1, 3, 7, ...
NullUserException


8
आप math.fmodC या Java के समान व्यवहार प्राप्त करने के लिए उपयोग कर सकते हैं ।
0x2b3bfa0

जवाबों:


136

C या C ++ के विपरीत, Python के modulo ऑपरेटर ( %) में हमेशा एक संख्या होती है, जिसमें हर (विभाजक) के समान चिन्ह होता है। आपकी अभिव्यक्ति की पैदावार 3 है क्योंकि

(-5) / ४ = -१.२५ -> मंजिल (-१.२५) = -२

(-5)% ४ = (-२ × ४ + ३)% ४ = ३।

यह सी व्यवहार पर चुना जाता है क्योंकि एक nonnegative परिणाम अक्सर अधिक उपयोगी होता है। एक उदाहरण सप्ताह के दिनों की गणना करना है। यदि आज मंगलवार (दिन # 2) है, तो सप्ताह का दिन N दिन पहले क्या है? अजगर में हम गणना कर सकते हैं

return (2 - N) % 7

लेकिन C में, यदि N , 3 है, तो हमें एक ऋणात्मक संख्या मिलती है जो एक अमान्य संख्या है, और हमें इसे 3 जोड़कर मैन्युअल रूप से ठीक करने की आवश्यकता है:

int result = (2 - N) % 7;
return result < 0 ? result + 7 : result;

( Http://en.wikipedia.org/wiki/Modulo_operator देखें कि अन्य भाषाओं के लिए परिणाम का संकेत कैसे निर्धारित किया जाता है।)


6
हैरानी की बात है, पायथन के सापेक्ष ऑपरेटर (%) नहीं है हमेशा एक नंबर विभाजक (भाजक) के रूप में एक ही हस्ताक्षर होने लौट आते हैं। देखें stackoverflow.com/questions/48347515/...
zezollo

33

यहाँ Guido वैन Rossum से एक स्पष्टीकरण है:

http://python-history.blogspot.com/2010/08/why-pythons-integer-division-floors.html

अनिवार्य रूप से, यह ऐसा है कि a / b = q शेष r के साथ रिश्तों को संरक्षित करता है b * q + r = a और 0 <= r <b।


4
सी ++ और जावा जैसी भाषाएं भी पहले रिश्ते को संरक्षित करती हैं, लेकिन वे नकारात्मक a, सकारात्मक के लिए bछत करते हैं, जबकि पायथन फर्श। यह हमेशा सच है कि abs(r) < b, और वे iff छत r <= 0
इवगेनी सर्गेव

9

ऋणात्मक संख्याओं के साथ पूर्णांक विभाजन और मॉड को संभालने का कोई सबसे अच्छा तरीका नहीं है। यह अच्छा होगा यदि a/bसमान परिमाण और इसके विपरीत चिन्ह हों (-a)/b। यह अच्छा होगा यदि a % bवास्तव में एक मोडुलो बी। चूंकि हम वास्तव में चाहते हैं a == (a/b)*b + a%b, पहले दो असंगत हैं।

किसको रखना है यह एक मुश्किल सवाल है, और दोनों पक्षों के लिए तर्क हैं। C और C ++ राउंड पूर्णांक विभाजन शून्य (तो a/b == -((-a)/b)) की ओर है , और जाहिर तौर पर पायथन नहीं है।


1
"अच्छा होगा यदि a / b समान परिमाण और (-a) / b के विपरीत चिन्ह हो।" क्यों अच्छा होगा? वह वांछित व्यवहार कब है?
user76284

क्योंकि यह तब नियमित विभाजन और गुणन के समान कार्य करेगा, और इस तरह से सहज रूप से काम करना आसान है। हालांकि यह गणितीय रूप से समझ में नहीं आता है।
Demis

6

जैसा कि बताया गया है, पायथन मोडुलो अन्य भाषाओं के सम्मेलनों के लिए एक अच्छी तरह से अपवाद बनाता है ।

यह नकारात्मक संख्या एक सहज व्यवहार है, खासकर जब साथ संयोजन में उपयोग देता है //पूर्णांक-विभाजित ऑपरेटर, के रूप में %सापेक्ष अक्सर (गणित में के रूप में। है divmod ):

for n in range(-8,8):
    print n, n//4, n%4

पैदा करता है:

 -8 -2 0
 -7 -2 1
 -6 -2 2
 -5 -2 3

 -4 -1 0
 -3 -1 1
 -2 -1 2
 -1 -1 3

  0  0 0
  1  0 1
  2  0 2
  3  0 3

  4  1 0
  5  1 1
  6  1 2
  7  1 3
  • पायथन %हमेशा शून्य या सकारात्मक * आउटपुट करता है
  • पायथन //हमेशा नकारात्मक अनंत की ओर गोल होता है

* - जब तक सही ऑपरेंड सकारात्मक है। दूसरी ओर11 % -10 == -9


धन्यवाद अपने उदाहरण मुझे यह समझ बनाया :)
Lamis

5

में अजगर , सापेक्ष ऑपरेटर इस तरह काम करता है।

>>> mod = n - math.floor(n/base) * base

तो परिणाम है (आपके मामले के लिए):

mod = -5 - floor(-1.25) * 4
mod = -5 - (-2*4)
mod = 3

जबकि अन्य भाषाएं जैसे C, JAVA, JavaScript फर्श के बजाय ट्रंकेशन का उपयोग करती हैं।

>>> mod = n - int(n/base) * base

जिसके परिणामस्वरूप:

mod = -5 - int(-1.25) * 4
mod = -5 - (-1*4)
mod = -1

यदि आपको अजगर में गोलाई के बारे में अधिक जानकारी चाहिए, तो इसे पढ़ें ।


3

मोडुलो, 4 के लिए समतुल्यता वर्ग:

  • 0: 0, 4, 8, 12 ... और -4, -8, -12 ...
  • 1: 1, 5, 9, 13 ... और -3, -7, -11 ...
  • 2: 2, 6, 10 ... और -2, -6, -10 ...
  • 3: 3, 7, 11 ... और -1, -5, -9 ...

यहां नकारात्मक संख्याओं के साथ मोडुलो के व्यवहार की एक कड़ी दी गई है । (हाँ, मैंने इसे देखा)


@NullUserException - yup, यह थी। तय की। धन्यवाद।
गेहूं

1

मुझे यह भी लगा कि यह पायथन का एक अजीब व्यवहार था। यह पता चला है कि मैं विभाजन को अच्छी तरह से हल नहीं कर रहा था (कागज पर); मैं भागफल को 0 का मान दे रहा था और शेष को -5 का मान दे रहा था। भयानक ... मैं पूर्णांक संख्याओं के ज्यामितीय प्रतिनिधित्व को भूल गया। संख्या रेखा द्वारा दिए गए पूर्णांकों की ज्यामिति को याद करके, कोई भी भागफल और शेष के लिए सही मान प्राप्त कर सकता है और जाँच सकता है कि पायथन का व्यवहार ठीक है। (हालांकि मैं यह मानता हूं कि आप पहले ही अपनी चिंता का समाधान कर चुके हैं)।


1

यह भी उल्लेख के लायक है कि अजगर में भी विभाजन सी: विचार से अलग है

>>> x = -10
>>> y = 37

सी में आप परिणाम की उम्मीद करते हैं

0

अजगर में x / y क्या है?

>>> print x/y
-1

और% modulo है - शेष नहीं! जबकि C पैदावार में x% y है

-10

अजगर की पैदावार।

>>> print x%y
27

आप सी में दोनों प्राप्त कर सकते हैं

विभाजन:

>>> from math import trunc
>>> d = trunc(float(x)/y)
>>> print d
0

और शेष (ऊपर से विभाजन का उपयोग करके):

>>> r = x - d*y
>>> print r
-10

यह गणना शायद सबसे तेज़ नहीं है, लेकिन यह x और y के किसी भी संकेत संयोजन के लिए काम कर रहा है, सी प्लस में वही परिणाम प्राप्त करने के लिए जो यह सशर्त बयानों से बचता है।

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