प्रोग्रामिंग भाषा डिजाइनर जब यह निर्णय लेते हैं कि मॉडुलो ऑपरेशन में क्या संकेत मिलता है?


9

के माध्यम से जा रहे हैं Modulo आपरेशन (एवेन्यू, जबकि बीच का अंतर की खोज करें जो मैंने दर्ज remऔरmod ) मैं भर में आया था:

गणित में मोडुलो ऑपरेशन का परिणाम यूक्लिडियन डिवीजन का शेष है। हालांकि, अन्य सम्मेलन संभव हैं। कंप्यूटर और कैलकुलेटर में संख्याओं के भंडारण और प्रतिनिधित्व के विभिन्न तरीके हैं; इस प्रकार मोडुलो ऑपरेशन की उनकी परिभाषा प्रोग्रामिंग भाषा और / या अंतर्निहित हार्डवेयर पर निर्भर करती है।

प्रशन:

  • यूक्लिडियन डिवीजन के माध्यम से जाने पर मैंने पाया कि इस ऑपरेशन का अवशेष हमेशा सकारात्मक होता है (या 0)। अंतर्निहित कंप्यूटर हार्डवेयर की प्रोग्रामिंग भाषा डिजाइनरों को गणित से अलग करने के लिए क्या सीमा है?
  • हर प्रोग्रामिंग लैंग्वेज में इसे पूर्वनिर्धारित या अपरिभाषित किया जाता है, नियम जिसके अनुसार मोडुलो ऑपरेशन का परिणाम यह हो जाता है। इन नियमों को बनाते समय क्या औचित्य अपनाया जाता है? और अगर अंतर्निहित हार्डवेयर चिंता का विषय है, तो क्या नियम उस हिसाब से नहीं बदलने चाहिए, जो प्रोग्रामिंग भाषा से स्वतंत्र है?

1
मेरे कोड में मुझे लगभग हमेशा modulo की आवश्यकता है शेष नहीं। पता नहीं क्यों शेष इतना लोकप्रिय है।
कोडइन्चौस

8
संबंधित क्या अंतर है? रेमेडर बनाम मोडुलस - एरिक लिपर्ट का ब्लॉग (सी # डिजाइनरों में से एक द्वारा, लेकिन मेरा मानना ​​है कि वह इस निर्णय के बाद टीम में शामिल हो गए)
कोडइन्चोस

1
यदि आप विकिपीडिया लेख (आपके द्वारा उद्धृत भाग से परे) पढ़ना जारी रखते हैं, तो यह बताता है कि आपने क्या अच्छी तरह उद्धृत किया है। उस स्पष्टीकरण के बारे में आप किस उलझन में हैं?
रॉबर्ट हार्वे

1
एक संबंधित प्रश्न सीपीयू निर्देशों के लिए इन कार्यों में से कौन सा सीधे नक्शे में है। सी में यह कार्यान्वयन परिभाषित है, जो संभव के रूप में कई प्लेटफार्मों पर हार्डवेयर पर सीधे मैपिंग के सी दर्शन के साथ फिट बैठता है। इसलिए यह उन सामानों को निर्दिष्ट नहीं करता है जो CPU के बीच भिन्न हो सकते हैं।
कोडइन्चोस

5
@BleedingFingers प्रोग्रामिंग अक्सर पूर्णांक विभाजन का उपयोग करता है जो शून्य की ओर जाता है, जैसे (-3)/2 == -1। यह परिभाषा उपयोगी हो सकती है। जब आप %इस विभाजन के अनुरूप होना चाहते हैं तो आप C # में उपयोग x == (x/y)*y + x % yकी परिभाषा को पूरा करते हैं %
कोडइंचाचोस

जवाबों:


7

सभी आधुनिक कंप्यूटरों का हार्डवेयर, या तो बिना (या तुच्छ) प्रदर्शन प्रभाव के साइन के मॉड संचालन को लागू करने के लिए पर्याप्त रूप से शक्तिशाली है। यह कारण नहीं है।

अधिकांश कंप्यूटर भाषाओं की सामान्य अपेक्षा यह है कि (a div b) * b + (a mod b) = a। दूसरे शब्दों में, div और mod को एक साथ एक संख्या को भागों में विभाजित करते हैं जो मज़बूती से फिर से एक साथ वापस रख सकते हैं। यह आवश्यकता C ++ मानक में स्पष्ट है। यह अवधारणा बहुआयामी सरणियों के अनुक्रमण से निकटता से संबंधित है। मैंने अक्सर इसका इस्तेमाल किया है।

इससे यह देखा जा सकता है कि div और mod एक if b के पॉजिटिव को संरक्षित करेगा (जैसा कि आमतौर पर होता है)।

कुछ भाषाएं एक 'रेम ()' फ़ंक्शन प्रदान करती हैं जो मॉड से संबंधित है और कुछ अन्य गणितीय औचित्य हैं। मुझे इसका इस्तेमाल करने की कभी जरूरत नहीं पड़ी। उदाहरण के लिए देखें फ्रीम () में ग्नू सी। [संपादित करें]


मुझे लगता है कि अगर यह सकारात्मक है या यदि यह नहीं है, तो इसकी rem(a,b)संभावना अधिक है। mod(a,b)mod(a,b) + b
14:40 पर user40989

3
(a div b) * b + (a mod b) = a- यह, बहुत बहुत। वास्तव में, यूक्लिडियन विभाग में विकिपीडिया इसे नकारात्मक संख्याओं तक पहुंचाने का वर्णन करता है (विशेष रूप से "शेष केवल चार संख्याओं में से एक है जो कभी भी नकारात्मक नहीं हो सकती है।") मुझे भ्रमित करता है क्योंकि मुझे हमेशा सिखाया गया था कि शेष नकारात्मक हो सकता है। उस स्तर पर हर गणित वर्ग में।
इजाकाता

@ user40989: मैंने कहा कि मैंने कभी इसका इस्तेमाल नहीं किया। संपादित देखें!
david.pfx

4

प्रोग्रामिंग के लिए आम तौर पर आप चाहते हैं X == (X/n)*n + X%n; इसलिए मॉडुलो को कैसे परिभाषित किया जाता है यह इस बात पर निर्भर करता है कि पूर्णांक विभाजन कैसे परिभाषित किया गया था।

इसे ध्यान में रखते हुए, आप वास्तव में पूछ रहे हैं " जब प्रोग्रामिंग भाषा डिजाइनर तय करते हैं कि पूर्णांक विभाजन कैसे काम करता है? "

वास्तव में लगभग 7 विकल्प हैं:

  • नकारात्मक अनंत के लिए दौर
  • सकारात्मक अनंत के लिए दौर
  • दौर से लेकर शून्य तक
  • "राउंड टू नज़दीकी" के कई संस्करण (अंतर के साथ कि कैसे 0.5 जैसा कुछ गोल है)

अब विचार करें -( (-X) / n) == X/n। मैं चाहता हूं कि यह सच हो, क्योंकि कुछ भी असंगत लगता है (यह फ्लोटिंग पॉइंट के लिए सच है) और अतार्किक (कीड़े का एक संभावित कारण और एक संभावित चूक अनुकूलन)। यह पूर्णांक विभाजन के लिए पहले 2 विकल्प बनाता है (या तो अनंत की ओर घूमता है) अवांछनीय है।

"गोल से निकटतम" विकल्पों में से सभी प्रोग्रामिंग के लिए गर्दन में दर्द हैं, खासकर जब आप बिटमैप (जैसे offset = index / 8; bitNumber = index%8;) कुछ कर रहे हैं ।

यह "संभावित रूप से सबसे अधिक समझदार" विकल्प के रूप में शून्य की ओर घूमता है, जिसका अर्थ है कि modulo अंश (या शून्य) के समान चिह्न के साथ एक मान लौटाता है।

नोट: आप यह भी ध्यान देंगे कि अधिकांश सीपीयू (सभी सीपीयू जो मुझे ज्ञात हैं) पूर्णांक विभाजन को उसी "गोल से शून्य" तरीके से करते हैं। यह उन्हीं कारणों से होने की संभावना है।


लेकिन ट्रंकिंग डिवीजन की अपनी विसंगतियां भी हैं: यह टूटता है (a+b*c)/b == a % bऔर a >> n == a / 2 ** n, जिसके लिए फ्लोर्ड डिवीजन में व्यवहार होता है।
dan04

आपका पहला उदाहरण समझ में नहीं आता है। आपका दूसरा उदाहरण प्रोग्रामर्स के लिए एक गड़बड़ है: सकारात्मक ए और पॉजिटिव एन के लिए यह सुसंगत है, नकारात्मक ए और पॉजिटिव एन के लिए, यह इस बात पर निर्भर करता है कि शिफ्ट राइट को कैसे परिभाषित किया गया है (अंकगणितीय बनाम तार्किक), और नकारात्मक एन के लिए यह टूट गया है (जैसे 1 >> -2 == a / 2 ** (-2))।
ब्रेंडन

पहला उदाहरण एक टाइपो था: मेरा मतलब है (a + b * c) % b == a % b, %ऑपरेटर, लाभांश में आवधिक-आवधिक है, जो अक्सर महत्वपूर्ण होता है। उदाहरण के लिए, फ्लोर्ड डिवीजन के साथ, day_count % 7आपको सप्ताह का दिन देता है, लेकिन ट्रंचिंग डिवीजन के साथ, यह युग से पहले की तारीखों के लिए टूट जाता है।
dan04

0

सबसे पहले, मैं दोहराता हूं कि एक मोडुलो बी - बी * (एक डी बी) के बराबर होना चाहिए, और यदि कोई भाषा प्रदान नहीं करती है, तो आप एक भयानक गणितीय गड़बड़ी में हैं। वह अभिव्यक्ति a - b * (a div b) वास्तव में है कि कितने कार्यान्वयन एक modulo b की गणना करते हैं।

कुछ संभावित तर्क हैं। पहला यह है कि आप अधिकतम गति चाहते हैं, इसलिए एक div b को परिभाषित किया जाता है जो भी प्रोसेसर का उपयोग करेगा वह प्रदान करेगा। यदि आपके प्रोसेसर में एक "div" निर्देश है, तो एक div b वह है जो div निर्देश करता है (जब तक कि यह कुछ पूरी तरह से पागल नहीं है)।

दूसरा यह है कि आप कुछ विशिष्ट गणितीय व्यवहार चाहते हैं। चलो पहले मान लेते हैं b> 0. यह काफी उचित है कि आप चाहते हैं कि div b का परिणाम शून्य की ओर हो। तो 4 डिव 5 = 0, 9 डिव 5 = 1, -4 डिव 5 = -0 = 0, -9 डिव 5 = -1। यह आपको (-a) div b = - (a div b) और (-a) modulo b = - (a modulo b) देता है।

यह काफी उचित है लेकिन सही नहीं है; उदाहरण के लिए (a + b) div b = (a div b) + 1 धारण नहीं करता है, अगर a = -1 कहें। एक निश्चित b> 0 के साथ, आम तौर पर (b) संभव मान ऐसे होते हैं कि div b समान परिणाम देता है, सिवाय 2b के - 1 मान a -b + 1 से b-1 जहां div b बराबर होता है 0 इसका मतलब यह भी है कि अगर कोई ऋणात्मक है तो एक मोडुलो बी ऋणात्मक होगा। हम हमेशा 0 से b-1 तक की रेंज में एक मोडुल बी होना चाहते हैं।

दूसरी ओर, यह निवेदन करना भी काफी उचित है कि जैसे आप एक के क्रमिक मूल्यों से गुजरते हैं, एक मोडुलो बी को मानों के माध्यम से 0 से बी -1 तक जाना चाहिए और फिर 0 से शुरू करना चाहिए। और यह अनुरोध करने के लिए कि (a + b) div b होना चाहिए (a div b) + 1. उस लक्ष्य को प्राप्त करने के लिए, आप चाहते हैं कि div b का परिणाम गोलाकार की ओर हो, इसलिए -1 div b = -1। फिर, नुकसान हैं। (-ए) div b = - (a div b) धारण नहीं करता है। बार-बार दो या किसी संख्या b> 1 से भाग देने पर अंततः आपको 0 का परिणाम नहीं मिलेगा।

चूंकि संघर्ष होते हैं, इसलिए भाषाओं को तय करना होगा कि उनके लिए कौन सा लाभ अधिक महत्वपूर्ण है और उसी के अनुसार निर्णय लें।

नकारात्मक बी के लिए, अधिकांश लोग अपने सिर को चारों ओर नहीं ले सकते हैं जो एक div b और modulo b पहले स्थान पर होना चाहिए, इसलिए एक सरल तरीका यह परिभाषित करना है कि div b = (-a) div (-b) और a modulo b = (-a) modulo (-b) यदि b <0 है, या जो भी सकारात्मक b के लिए कोड का उपयोग करने का स्वाभाविक परिणाम है।

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