2011-08-15 18 views
72

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

यह

int c = (int)a/b; 
int d = a % b; 

या

int c = (int)a/b; 
int d = a - b * c; 

या

double tmp = a/b; 
int c = (int)tmp; 
int d = (int)(0.5+(tmp-c)*b); 

या

शायद वहाँ एक जादुई समारोह है कि एक बार में एक दोनों देता है? होगा

+4

नीचे दिए गए सभी उत्तर उचित प्रतीत होते हैं, मैं बस यह जोड़ना चाहूंगा कि 'डबल' (आपकी आखिरी वस्तु) के साथ कोई भी मकिंग मुझे एक बुरा विचार की तरह लगता है, आप उन संख्याओं के साथ समाप्त हो जाएंगे जो लाइन नहीं करते हैं, और आपको प्रदर्शन और निष्पादन योग्य आकार में खर्च हो सकता है (कुछ एम्बेडेड सिस्टम पर हमेशा मेरे लिए एक मुद्दा था)। – nhed

+2

तीसरा एक बीएडी विकल्प है: क्या होगा यदि tmp = 54.999999999999943157? यह कहा, पुरानी शैली कास्टिंग कभी करने के लिए एक चालाक बात नहीं है। – jimifiki

उत्तर

71

x86 पर शेष विभाजन का उप-उत्पाद है, इसलिए कोई भी अर्ध-सभ्य संकलक इसका उपयोग करने में सक्षम होना चाहिए (और div फिर से निष्पादित नहीं करना चाहिए)। यह शायद अन्य आर्किटेक्चर पर भी किया जाता है।

निर्देश: DIV src

नोट: अहस्ताक्षरित विभाजन। "Src" द्वारा संचयक (एएक्स) को विभाजित करता है। यदि divisor एक बाइट मान है, तो परिणाम AL पर और शेष को एएच पर रखा जाता है। यदि divisor एक शब्द मान है, तो DX: AX को "src" द्वारा विभाजित किया गया है और परिणाम को AX में संग्रहीत किया गया है और शेष DX में संग्रहीत है।

int c = (int)a/b; 
int d = a % b; /* Likely uses the result of the division. */ 
+6

मुझे लगता है कि कई स्कूल प्राथमिक स्कूल से जानते हैं कि जब एक विभाजन करते हैं तो आप शेष को मुफ्त में प्राप्त करते हैं। वास्तविक सवाल यह है: क्या हमारे कंपाइलर्स इसका लाभ लेने के लिए पर्याप्त स्मार्ट हैं? –

+0

सहमत हैं - लेकिन यदि बी 2 की शक्ति है तो आप थोड़ा बदलाव कर सकते हैं। –

+1

@jdv: मुझे आश्चर्य नहीं होगा। यह एक बहुत ही सरल अनुकूलन है। –

57

std::div दोनों परिणाम और शेष के साथ एक संरचना देता है।

+4

मुझे यह जानकर उत्सुकता है कि यह वास्तव में आधुनिक कंपाइलर पर विकल्प 1 से अधिक कुशल है या नहीं। –

+2

अच्छा, मुझे नहीं पता था। क्या यह तेज़ है? –

+0

अच्छा। क्या आपको पता चलेगा कि किसी को लंबे समय तक कहीं भी लागू किया गया है? – Cookie

-3

आप शेष प्राप्त करने के लिए एक मॉड्यूलस का उपयोग कर सकते हैं। यद्यपि @ cnicutar का जवाब क्लीनर/अधिक प्रत्यक्ष लगता है।

+1

हां, मूल पोस्टर ने मॉड्यूलस ऑपरेटर का उपयोग किया, सवाल यह है कि इसे कैसे कुशल बनाना है। –

3

अन्य सभी बराबर हैं, सबसे अच्छा समाधान वह है जो स्पष्ट रूप से आपके इरादे को व्यक्त करता है। तो:

int totalSeconds = 453; 
int minutes = totalSeconds/60; 
int remainingSeconds = totalSeconds % 60; 

शायद आपके द्वारा प्रस्तुत किए गए तीन विकल्पों में से सबसे अच्छा है। जैसा कि अन्य उत्तरों में उल्लेख किया गया है, div विधि एक बार में आपके लिए दोनों मानों की गणना करेगा।

+3

स्पष्ट रूप से सवाल गति के बारे में पूछ रहा है ... – Pacerier

21

कम से कम x86 पर, g ++ 4.6.1 केवल आईडीआईवीएल का उपयोग करता है और दोनों एकल निर्देशों से मिलता है।

सी ++ कोड:

void foo(int a, int b, int* c, int* d) 
{ 
    *c = a/b; 
    *d = a % b; 
} 

86 कोड:

__Z3fooiiPiS_: 
LFB4: 
    movq %rdx, %r8 
    movl %edi, %edx 
    movl %edi, %eax 
    sarl $31, %edx 
    idivl %esi 
    movl %eax, (%r8) 
    movl %edx, (%rcx) 
    ret 
+0

क्या आदेश मायने रखता है? उदाहरण के लिए यदि आप '/ =' पर पुनरावृत्त कर रहे हैं - आपको पहले विभाजन को रखने के लिए अस्थायी चर का उपयोग करने की आवश्यकता हो सकती है। – Annan

6

नमूना कोड परीक्षण div() और संयुक्त विभाजन & आधुनिक। मैंने इन्हें जीसीसी-ओ 3 के साथ संकलित किया, मुझे कॉल करने के लिए कुछ भी अनुकूलित करने से रोकने के लिए कुछ भी नहीं करना था (आउटपुट विभाजन + मॉड समाधान के लिए 0 होगा)।

#include <stdio.h> 
#include <sys/time.h> 
#include <stdlib.h> 

extern doNothing(int,int); // Empty function in another compilation unit 

int main() { 
    int i; 
    struct timeval timeval; 
    struct timeval timeval2; 
    div_t result; 
    gettimeofday(&timeval,NULL); 
    for (i = 0; i < 1000; ++i) { 
     result = div(i,3); 
     doNothing(result.quot,result.rem); 
    } 
    gettimeofday(&timeval2,NULL); 
    printf("%d",timeval2.tv_usec - timeval.tv_usec); 
} 

आउटपुट: 150

#include <stdio.h> 
#include <sys/time.h> 
#include <stdlib.h> 

extern doNothing(int,int); // Empty function in another compilation unit 

int main() { 
    int i; 
    struct timeval timeval; 
    struct timeval timeval2; 
    int dividend; 
    int rem; 
    gettimeofday(&timeval,NULL); 
    for (i = 0; i < 1000; ++i) { 
     dividend = i/3; 
     rem = i % 3; 
     doNothing(dividend,rem); 
    } 
    gettimeofday(&timeval2,NULL); 
    printf("%d",timeval2.tv_usec - timeval.tv_usec); 
} 

आउटपुट:

को एक अलग नज़रिए अपने साथ ले जाएं 25

3

आप भरोसा नहीं कर सकते छ ++ एक पर 64 बिट पूर्णांकों के साथ यहाँ 4.6.3 32 बिट इंटेल मंच। ए/बी को divdi3 पर कॉल द्वारा गणना की जाती है और% बी को moddi3 पर कॉल द्वारा गणना की जाती है। मैं एक उदाहरण के साथ भी आ सकता हूं जो इन कॉल के साथ ए/बी और ए-बी * (ए/बी) की गणना करता है। तो मैं सी = ए/बी और ए-बी * सी का उपयोग करता हूं।

div विधि एक फ़ंक्शन को कॉल करता है जो div संरचना की गणना करता है, लेकिन एक फ़ंक्शन कॉल प्लेटफॉर्म पर अक्षम होता है जिसमें अभिन्न प्रकार (64 बिट इंटेल/एमएमडी प्लेटफ़ॉर्म पर 64 बिट पूर्णांक) के लिए हार्डवेयर समर्थन होता है।

5

कार्यों के ऊपर उल्लिखित std::div परिवार के अलावा, वहाँ भी कार्यों का std::remquo परिवार, एक पारित कर दिया-में सूचक के माध्यम से रेम -ainder और यथास्थिति -tient हो रही वापस जाएँ।

[संपादित करें]] यह std :: remquo doesn't really return the quotient जैसा दिखता है।

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