2009-10-30 15 views
11

का उपयोग कर 64 बिट संख्याओं को जोड़ना हम 32 बिट अंकगणित का उपयोग करके दो 64 बिट संख्याओं को कैसे जोड़ सकते हैं ??32 बिट अंकगणित

उत्तर

22

पहले कम से कम महत्वपूर्ण बाइट जोड़ें, वाह रखें। सबसे महत्वपूर्ण बाइट्स LSBs से कैरी पर विचार करें:

; x86 assembly, Intel syntax 
; adds ecx:ebx to edx:eax 
add eax, ebx 
adc edx, ecx 
+0

लेकिन हस्ताक्षर किए जाने के बारे में क्या? –

+6

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

-2

आप मैन्युअल रूप से प्रत्येक 32 बिट हिस्सा जोड़ सकते हैं और मैन्युअल रूप से कैरी की देखभाल कर सकते हैं।

6

64-बिट संख्या कर रहे हैं (एक , एक) और (ख , ख), जहां एक्स उच्च 32 बिट अहस्ताक्षरित के रूप में लिया है , और x कम 32 बिट्स को हस्ताक्षरित के रूप में लिया गया है, तो दो संख्याओं का योग नीचे दिया गया है।

c1 = a1 + b1 

c2 = a2 + b2 

if (c1 < a1 || c1 < b1) 
    c2 += 1 
+0

सुनिश्चित करें कि ए 1, बी 1, सी 1 सही ढंग से काम करने की तुलना के लिए हस्ताक्षरित हैं। –

+0

बीटीडब्लू ... अगर हमें केवल दो 64 बिट नंबर दिए गए हैं तो ए 1, बी 1, ए 2 और बी 2 क्या हैं ?? –

+0

@all, टिप्पणियों के लिए धन्यवाद। मैंने जवाब कुछ हद तक भरने की कोशिश की है। – DigitalRoss

15

विचार करें कि आप 1 अंकों के अंकगणितीय का उपयोग करके दो 2 अंकों की संख्या कैसे जोड़ते हैं।

42 
+39 
--- 

सबसे पहले आप सही कॉलम जोड़ते हैं। ("वाले" या "इकाइयां")। 2 + 9 11. 11 "overflowed" अपने 1 अंकीय अंकगणित है, तो आप "ले" के लिए 10.

1 
42 
+39 
--- 
    1 

अब आप बाईं "दसियों" कॉलम को जोड़ने, कैरी सहित है। 1 + 4 + 3 = 8।

1 
42 
+39 
--- 
81 

8 10 से कम है, इसलिए कोई वाह नहीं है। हो गया।

अभी क्या हुआ? जब आप कहते हैं कि एक नंबर "42" है (आधार 10 में) क्या तुम सच में मतलब

4*10+2 

या, समतुल्य रूप,

4*10^1+2*10^0 

(जब मैं कहता हूँ "एक^b", जैसे "10^1 ", मेरा मतलब है" बी'एथ पावर को उठाया गया ": एक बार बी गुणा करके गुणा किया गया। 10^0 है 1. 10^1 है 10. 10^2 10 * 10 = 100 ...)

जब आप जोड़ने के "42" और "39" आप

4*10+2+3*10+9 
कह रहे हैं 210

कौन सा

(4+3)*10+(2+9)*1 
(4+3)*10+(11)*1 
(4+3)*10+(1*10+1)*1 

के बराबर होती है अब के बाद से "11" एक वैध एक अंक की संख्या नहीं है, आप लोगों से 10 ले जाने के लिए की जरूरत है, दहाई के स्थान में एक 1 में बदलकर।

(4+3)*10+(1)*10+(1)*1 
(4+3+1)*10+(1)*1 
(8)*10+(1)*1 

जो है 81.

तो, क्यों मैं इस बारे में नहीं बल्कि अपने प्रश्न से लगभग 64 बिट संख्या और 32 बिट गणित में बात कर रहे हैं? क्योंकि वे वास्तव में वही हैं!

एक अंक 0 से 9 तक है। ए "32 बिट नंबर" 0 से 2^32-1 तक है। (मान लीजिए कि यह हस्ताक्षरित है।)

तो, बेस 10 में काम करने के बजाय, चलिए बेस 2^32 में काम करते हैं। आधार 2^32 में, हम 10 के रूप में 2^32 लिखना आप आधार 2^32 में एक 64 बिट संख्या लिखते हैं, यह होगा

(x)*10+y 

जहां x और y 0 और 2 के बीच संख्या के लिए प्रतीक हैं^32-1। वे प्रतीकों बिटरस्ट्रिंग हैं।

आप दो 64 बिट संख्या जोड़ने के लिए, आधार में उन्हें टूट चाहते हैं 2^32 के रूप में:

a_1*10+a_0 
+b_1*10+b_0 

अब आप उन्हें आधार में 2^32 में ठीक उसी तरह से जोड़ने आप आधार 10 में उन्हें जोड़ने - बस, 32 बिट अंकगणितीय का उपयोग करके आप अंक अंकगणित का उपयोग करने के बजाय जोड़ने के बजाय!

आप 64 बिट संख्या को दो 32 बिट संख्याओं a_1 और a_0 में कैसे विभाजित करते हैं? 2^32 द्वारा विभाजित करें। फ्लोटिंग पॉइंट में नहीं, लेकिन पूर्णांक - जहां आपको लाभांश और शेष मिलता है। लाभांश a_1 है, शेष A_0 है।

दुर्भाग्य से 64 बिट अंकगणितीय की आवश्यकता है। हालांकि, आम तौर पर a_1 एक की "सबसे महत्वपूर्ण आधा" है, इसलिए, सी शैली वाक्य रचना में:

a_1=(a >> 32) 
a_0=(a & 0xFFFFFFFF) 

जहां >> एक सही bitshift है और & बिटवाइज़ और है।

आमतौर पर यदि आप 64 बिट अतिरिक्त नहीं कर सकते हैं, तो "64 बिट नंबर" वास्तव में दो 32 बिट संख्या a_1 और a_0 होगा। यदि आप uint64_t अंकगणित नहीं कर सकते हैं तो आपके पास uint64_t नहीं होगा!

यह सब मानते हैं कि आप हस्ताक्षरित अंकगणित कर रहे हैं, लेकिन संकेतों से निपटना यहां से आसान है।

7

सी कोड पहले से तैनात अनावश्यक रूप से अत्यधिक शब्द है:

unsigned a1, b1, a2, b2, c1, c2; 

c1 = a1 + b1; 
c2 = a2 + b2; 

if (c1 < a1) 
    c2++; 

'a1' में 'अगर' 'बी 1' के साथ-साथ प्रतिस्थापित किया जा सकता है। अतिप्रवाह पर, सी 1 ए 1 और बी 1 दोनों से कम होगा।

+0

वास्तव में बहुत ही सुरुचिपूर्ण। –

3

यह इस

/* break up the 64bit number into smaller, 16bit chunks */ 
struct longint { 
    uint16 word0; 
    uint16 word1; 
    uint16 word2; 
    uint16 word3; 
}; 

uint16 add(longint *result, longint *a, longint *b) 
{ 
    /* use an intermediate large enough to hold the result 
     of adding two 16 bit numbers together. */ 
    uint32 partial; 

    /* add the chunks together, least significant bit first */ 
    partial = a->word0 + b->word0; 

    /* extract thie low 16 bits of the sum and store it */ 
    result->word0 = partial & 0x0000FFFF; 

    /* add the overflow to the next chunk of 16 */ 
    partial = partial >> 16 + a->word1 + b->word1; 
    /* keep doing this for the remaining bits */ 
    result->word1 = partial & 0x0000FFFF; 
    partial = partial >> 16 + a->word2 + b->word2; 
    result->word2 = partial & 0x0000FFFF; 
    partial = partial >> 16 + a->word3 + b->word3; 
    result->word3 = partial & 0x0000FFFF; 
    /* if the result overflowed, return nonzero */ 
    return partial >> 16; 
} 

वास्तविक हार्डवेयर की तरह कुछ एक समय में 16 बिट जोड़ने के लिए 32 बिट का उपयोग नहीं करता लग रहा है, कैरी का केवल एक अतिरिक्त बिट कभी इसके लिए आवश्यक है, और लगभग सभी CPU के एक है जब कोई अतिरिक्त ऑपरेशन ओवरफ्लो हो जाता है, तो स्टेटस फ्लैग ले जाएं, इसलिए यदि आप 32 बिट सीपीयू का उपयोग कर रहे हैं, तो आप 64 बिट ऑपरेशंस को दो, 32 बिट ऑपरेशंस में जोड़ सकते हैं।

1

बहुत अधिक प्रोसेसर में ले जाने वाला और अतिरिक्त-कैर्री ऑपरेशन होता है, जिसे आप केवल इस बारे में परवाह करते हैं कि आप असेंबली में प्रोग्रामिंग कर रहे हैं या नहीं। यदि आप एक उच्च भाषा का उपयोग कर रहे हैं, तो कंपाइलर सटीक उसी ऐड-इन-कैरी ऑपरेशंस को डंप करता है। मेरे एवीआर-जीसीसी ने मुझे दो 16-बिट संख्या जोड़ते समय दिया - एवीआर 8-बिट है - लेकिन उच्च अवधारणाओं के लिए एक ही अवधारणा लागू होगी। R2 और R3: R4:

ADD R2,R4 ; first add the two low-bytes, result stored into R2 
ADC R1,R3 ; then the two high-bytes and the carry bit, into R1 

परिणाम आर 1 में संग्रहीत किया जाता है:

को देखते हुए नंबर रजिस्टर आर 1 में हैं R2।

+0

विस्तारित 64 बिट रजिस्टरों का उपयोग करते समय 64 बिट अंकगणित 32 बिट संख्याओं का उपयोग क्यों करते हैं? –

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