2008-12-04 5 views
35

Haskell रिपोर्ट से:quotRem और divMod के बीच अंतर कब उपयोगी है?

quot, रेम, div, और आधुनिक वर्ग तरीकों इन कानूनों को संतुष्ट करता है, तो y गैर-शून्य है:

(x `quot` y)*y + (x `rem` y) == x 
(x `div` y)*y + (x `mod` y) == x 

quot पूर्णांक विभाजन की ओर छोटा कर दिया है शून्य, जबकि div का परिणाम नकारात्मक अनंतता के लिए छोटा कर दिया गया है।

उदाहरण के लिए:

Prelude> (-12) `quot` 5 
-2 
Prelude> (-12) `div` 5 
-3 

क्या जहां के कुछ उदाहरण कैसे परिणाम छोटा कर दिया मामलों है के बीच अंतर कर रहे हैं?

उत्तर

35

कई भाषाओं में "mod" या "%" ऑपरेटर होता है जो विभाजन के बाद शेष को 0 की ओर छंटनी के साथ देता है; उदाहरण सी, सी ++, जावा, और शायद सी # के लिए कहते थे:

(-11)/5 = -2 
(-11)%5 = -1 
5*((-11)/5) + (-11)%5 = 5*(-2) + (-1) = -11. 

हास्केल के quot और rem इस व्यवहार की नकल करना है। मैं कल्पना कर सकता हूं कि कुछ सी प्रोग्राम के आउटपुट के साथ संगतता कुछ विकसित स्थिति में वांछनीय हो सकती है।

हास्केल के div और mod, और बाद में अजगर का/और%, हमेशा विभाजन नीचे छोटा गणितज्ञों (कम से कम संख्या-सिद्धांतकारों) की परिपाटी निम्न (0 की ओर नहीं - नकारात्मक अनंत की ओर) ताकि शेष है हमेशा nonnegative। अजगर में इस प्रकार,

(-11)/5 = -3 
(-11)%5 = 4 
5*((-11)/5) + (-11)%5 = 5*(-3) + 4 = -11. 

हास्केल के div और mod इस व्यवहार का पालन करें।

+5

"ताकि शेष हमेशा नॉनगेटिव हो" तकनीकी रूप से, 'मोड' का संकेत दूसरे ऑपरेंड के संकेत का पालन करता है। – newacct

+0

हू, आप सही हैं। मैं इस डिजाइन निर्णय को समझ नहीं पा रहा हूं ... – ShreevatsaR

+0

यह संपत्ति को बनाए रखने के लिए है कि '(q, r) = divMod x y' अगर और केवल' x = q * y + r'। एक उदाहरण चलाएं, यह चालाक है कि यह कैसे काम करता है। – luqui

6

एक साधारण उदाहरण जहां यह कोई फर्क नहीं पड़ता है कि एक पूर्णांक भी अजीब है या नहीं।

let buggyOdd x = x `rem` 2 == 1 
buggyOdd 1 // True 
buggyOdd (-1) // False (wrong!) 

let odd x = x `mod` 2 == 1 
odd 1 // True 
odd (-1) // True 

नोट, ज़ाहिर है, आप बस इस तरह से अजीब परिभाषित करते हुए इन मुद्दों के बारे में सोच से बचने के सकता है:

let odd x = x `rem` 2 /= 0 
odd 1 // True 
odd (-1) // True 

सामान्य तौर पर, सिर्फ इतना है कि याद है, y > 0 के लिए, x mod y हमेशा कुछ लौट >= 0 जबकि x rem y 0 या x के समान संकेत के कुछ देता है।

23

यह आपके प्रश्न का बिल्कुल सही जवाब नहीं है, लेकिन जी 86 पर जीएचसी में, इंट पर उद्धरण एक मशीन निर्देश के लिए संकलित होगा, जबकि divMod काफी कुछ काम करता है। तो यदि आप एक गति-महत्वपूर्ण खंड में हैं और केवल सकारात्मक संख्याओं पर काम कर रहे हैं, तो quotRem जाने का रास्ता है।

+2

एसपीओजे प्राइम्स को हल करने के लिए, मोड के बजाय रिम का उपयोग करके मेरी टेस्ट फ़ाइल 5.533 के बजाय 4.758 में चलाती है। इसका मतलब यह है कि 32-बिट उबंटू, हास्केल प्लेटफ़ॉर्म 2011 के तहत तेज़ संस्करण 16% तेज है। –

+0

@ टिमपेरी, मुझे ऐसा नहीं लगता है। क्या होगा यदि आपने अपने पूरे कार्यक्रम में एक 'मोड' किया और उसी सुधार को देखा? – luqui

+0

मैंने कहा कि जब मैंने अपने प्राइम्स कोड में मोड से रीम में कॉल बदल दिए और मैंने 20% स्पीडअप देखा। यह एक सैद्धांतिक टिप्पणी नहीं है। यह एक घटना का विवरण था। मैंने केवल एक चीज बदल दी है (यद्यपि कई जगहें) और मैंने 20% स्पीडअप देखा। ऐसा लगता है कि 20% स्पीडअप * डीआईडी ​​* फॉलो है। –