2011-07-16 16 views
16

एक समारोह सी में div कहा जाता है, सी ++ (stdlib.h)div function उपयोगी है (stdlib.h)?

div_t div(int numer, int denom); 

typedef struct _div_t 
{ 
    int quot; 
    int rem; 
} div_t; 

लेकिन सी, सी है ++/और% ऑपरेटरों नहीं है।

मेरा प्रश्न है: "जब/और% ऑपरेटर होते हैं, तो div div उपयोगी है?"

+0

यह पहले से ही [इस सवाल] में उत्तर दिया गया था (http://stackoverflow.com/a/11726016/995714) –

उत्तर

13

div() फ़ंक्शन एक संरचना देता है जिसमें दूसरे पैरामीटर (संख्या) द्वारा पहले पैरामीटर (संख्यात्मक) के विभाजन का भाग और शेष होता है। चार वेरिएंट हैं:

  1. div_t div(int, int)
  2. ldiv_t ldiv(long, long)
  3. lldiv_t lldiv(long long, long long)
  4. imaxdiv_t imaxdiv(intmax_t, intmax_t

div_t संरचना इस तरह दिखता है (intmax_t सबसे बड़ी पूर्णांक सिस्टम पर उपलब्ध प्रकार का प्रतिनिधित्व करता है):

typedef struct 
    { 
    int quot;   /* Quotient. */ 
    int rem;   /* Remainder. */ 
    } div_t; 

कार्यान्वयन केवल / और % ऑपरेटरों का उपयोग करता है, इसलिए यह बिल्कुल जटिल या आवश्यक फ़ंक्शन नहीं है, लेकिन यह सी मानक का हिस्सा है (जैसा कि [आईएसओ 98 99: 201x] [1] द्वारा परिभाषित किया गया है)।)

/* Return the `div_t' representation of NUMER over DENOM. */ 
div_t 
div (numer, denom) 
    int numer, denom; 
{ 
    div_t result; 

    result.quot = numer/denom; 
    result.rem = numer % denom; 

    /* The ANSI standard says that |QUOT| <= |NUMER/DENOM|, where 
    NUMER/DENOM is to be computed in infinite precision. In 
    other words, we should always truncate the quotient towards 
    zero, never -infinity. Machine division and remainer may 
    work either way when one or both of NUMER or DENOM is 
    negative. If only one is negative and QUOT has been 
    truncated towards -infinity, REM will have the same sign as 
    DENOM and the opposite sign of NUMER; if both are negative 
    and QUOT has been truncated towards -infinity, REM will be 
    positive (will have the opposite sign of NUMER). These are 
    considered `wrong'. If both are NUM and DENOM are positive, 
    RESULT will always be positive. This all boils down to: if 
    NUMER >= 0, but REM < 0, we got the wrong answer. In that 
    case, to get the right answer, add 1 to QUOT and subtract 
    DENOM from REM. */ 

    if (numer >= 0 && result.rem < 0) 
    { 
     ++result.quot; 
     result.rem -= denom; 
    } 

    return result; 
} 
+1

@ जोर्जन: स्रोत वैसे भी कार्यान्वयन-परिभाषित है :-) – Vlad

+0

Vlad: स्पष्टीकरण के लिए मेरा उत्तर देखें। –

+1

विभाजन और शेष पर C11 (और C99?) Spec के साथ, एक अनुपालन कंपाइलर में भी 'numer> = 0 && result.rem <0' होगा? – chux

15

हां, यह है: यह एक ऑपरेशन में भाग्य और शेष की गणना करता है।

कि से

अलावा, समान व्यवहार / + % के साथ प्राप्त किया जा सकता है (और एक सभ्य अनुकूलक वैसे भी एक भी div में उन्हें अनुकूलित जाएगा)।

इसे समेटने के लिए: यदि आप प्रदर्शन के अंतिम बिट्स को निचोड़ने की परवाह करते हैं, तो यह आपकी पसंद का कार्य हो सकता है, खासकर यदि आपके प्लेटफ़ॉर्म पर ऑप्टिमाइज़र इतना उन्नत नहीं है। यह अक्सर एम्बेडेड प्लेटफॉर्म के मामले में होता है। अन्यथा, आप जिस भी तरीके से अधिक पठनीय पाते हैं उसका उपयोग करें।

+0

एक सभ्य अनुकूलक '/' और '%' को दो गुणाओं, थोड़ा बदलाव, और एक के साथ बदल देगा घटाव (ज्यादातर मामलों में)। –

+0

@Vlad: क्या आपका मतलब है कि एक ऑपरेशन में भाग्य और शेष की गणना करना इतना महत्वपूर्ण है कि एक नया फ़ंक्शन परिभाषित किया गया हो? –

+0

@बेन: 2 गुणा, बिट शिफ्ट और घटाव वास्तव में एक 'डीआईवी' निर्देश (इंटेल परिवार पर) से तेज है? – Vlad

2

यदि आपको दोनों मूल्यों की आवश्यकता है तो इसमें कम समय लगता है। सीपीयू हमेशा विभाजन करते समय शेष और मात्रा दोनों की गणना करता है। यदि एक बार "/" एक बार और "%" का उपयोग करें, तो cpu संख्या दो बार गणना करेगा।

(मेरे गरीब अंग्रेजी माफ, मैं देशी नहीं कर रहा हूँ)

+3

-1: यह कड़ाई से सही नहीं है, क्योंकि संकलक शायद इसे किसी भी तरह अनुकूलित कर देगा। इसके अलावा, div() को यह गारंटी देने के लिए एक अतिरिक्त जांच करना है कि परिणाम गैर-नकारात्मक है। –

+0

@ जोर्जन फोग दावा "div() को एक अतिरिक्त जांच करना है" सख्ती से सही नहीं है। विभिन्न प्रोसेसर "अतिरिक्त जांच" का उपयोग किये बिना 'div()' द्वारा निर्दिष्ट उद्धरण और शेष प्रदान करते हैं। यह एक मंच निर्भर मुद्दा है। एक चेक की आवश्यकता हो सकती है या हो सकता है। – chux

0

शायद क्योंकि कई प्रोसेसर पर div अनुदेश दोनों मूल्यों पैदा करता है और आप हमेशा एक ही पर कि आसन्न/और% ऑपरेटरों पहचान करने के लिए संकलक पर भरोसा कर सकते इनपुट एक ऑपरेशन में coalesced किया जा सकता है।

9

div के शब्दों (/% की अर्थ विज्ञान और, जो कुछ मामलों में महत्वपूर्ण है की तुलना में अलग है:

जीएनयू libc में कार्यान्वयन देखें।

if (numer >= 0 && result.rem < 0) 
    { 
     ++result.quot; 
     result.rem -= denom; 
    } 

% एक नकारात्मक जवाब वापस आ सकते हैं div जबकि() हमेशा एक गैर नकारात्मक शेष देता है,: यही कारण है कि निम्नलिखित कोड कार्यान्वयन मानसिक के जवाब में दिखाया गया है में है।

WikiPedia entry की जांच करें, विशेष रूप से "div हमेशा 0 की तरफ बढ़ता है, सी में सामान्य पूर्णांक विभाजन के विपरीत, जहां नकारात्मक संख्याओं के लिए गोलाकार कार्यान्वयन-निर्भर है।"

+0

यह सच नहीं है। 1) जब आप शून्य की ओर छंटनी करते हैं तो [शेष 'ऋणात्मक होगा यदि' संख्या <0'] (http://ideone.com/J28Gk9)। 2) सी 11 के बाद अंतर्निहित '/' और '%' शून्य की ओर छंटनी की गारंटी है, इसलिए 'div' को'/'और'% 'के समान करने के लिए परिभाषित किया गया है। – ybungalobill

3

div() भरा एक पूर्व C99 की जरूरत: एक नकारात्मक संकार्य साथ पोर्टेबिलिटी

Pre C99, a/b के भागफल के गोलाई दिशा कार्यान्वयन निर्भर था। div() के साथ, राउंडिंग दिशा वैकल्पिक नहीं है लेकिन को 0 div() पर समान पोर्टेबल डिवीजन प्रदान किया गया है। माध्यमिक उपयोग संभावित क्षमता थी जब कोड को शेष और शेष दोनों की गणना करने के लिए आवश्यक था।

C99 के साथ और बाद में, div() और / उसी दौर दिशा निर्दिष्ट करने और बेहतर compilers पास के a/b और a%b कोड के अनुकूलन के साथ, आवश्यकता कम हो गई।


यह div()और के लिए बाध्यकारी कारण था यह सी कल्पना में udiv_t udiv(unsigned numer, unsigned denom) के अभाव बताते हैं: नकारात्मक ऑपरेंड साथ a/b के कार्यान्वयन निर्भर परिणामों के मुद्दों पूर्व C99 में भी unsigned के लिए न के बराबर कर रहे हैं ।

संबंधित मुद्दे