math - x86-64 बिग पूर्णांक प्रतिनिधित्व?




biginteger arbitrary-precision (2)

मुझे लगता होगा यह सबसे अधिक सरणी के सबसे कम मूल्य के रूप में होगा। मैंने कोडांतरक में मनमाने ढंग से आकार की संख्याओं को जोड़ दिया। सीपीयू लेयर फ्लैग प्रदान करता है जो आपको इन प्रकार के आपरेशनों को आसानी से करने की अनुमति देता है। आप एक लूप लिखते हैं जो ऑपरेशन को बाइट आकार के हिस्सों में प्रदर्शित करता है लेयर फ्लैग "एड विथ लेय" निर्देश (एडीसी ऑपोडोड) का उपयोग करते हुए अगले ऑपरेशन में शामिल है।

उच्चतर प्रदर्शन कैसे करते हैं, x86-64 पर देशी बड़े-पूर्णांक पुस्तकालय स्मृति में एक बड़ा पूर्णांक का प्रतिनिधित्व करते हैं? (या यह भिन्नता है? क्या कोई सबसे आम तरीका है?)

नैवेली मैं आधार 2 64 में संख्याओं के 0-समाप्त स्ट्रिंग के रूप में उन्हें संग्रहीत करने के बारे में सोच रहा था।

उदाहरण के लिए X मेमोरी में है:

[8 bytes] Dn
.
.
[8 bytes] D2
[8 bytes] D1
[8 bytes] D0
[8 bytes] 0

चलो बी = 2 64

फिर

एक्स = डी एन * बी एन + ... + डी 2 * बी 2 + डी 1 * बी 1 + डी 0

खाली स्ट्रिंग (यानी शून्य के 8 बाइट्स) का मतलब शून्य है।

क्या यह उचित तरीका है? इस तरह के पेशेवरों और विपक्ष क्या हैं? क्या कोई बेहतर तरीका है?

आप हस्ताक्षर कैसे संभाल लेंगे? इस चर लंबाई मूल्य के साथ 2 पूरक काम करता है?

(यह पाया: http://gmplib.org/manual/Integer-Internals.html एक अंग क्या है?)


यहां मेरे पास बिग इंटिजर्स प्रसंस्करण के कुछ उदाहरण हैं I

इसके अलावा

सिद्धांत बहुत सरल है किसी भी बड़े अतिप्रवाह के लिए आपको CF (कैरी फ्लैग) का उपयोग करना होगा आइए दो 128-बिट संख्याओं के बारे में सोचें।

num1_lo: dq 1<<63
num1_hi: dq 1<<63
num2_lo: dq 1<<63
num2_hi: dq 1<<62
;Result of addition should be 0xC0000000 0x000000001 0x00000000 0x00000000
mov eax, dword [num1_lo]
mov ebx, dword [num1_lo+4]
mov ecx, dword [num1_hi]
mov edx, dword [num1_hi+4]

add eax, dword [num2_lo]
adc ebx, dword [num2_lo+4]
adc ecx, dword [num2_hi]
adc edx, dword [num2_hi+4]
jc .overflow

घटाव

इसके अलावा, आप CF को उधार लेते हैं, हालांकि इसके अतिरिक्त समान हैं।

mov eax, dword [num1_lo]
mov ebx, dword [num1_lo+4]
mov ecx, dword [num1_hi]
mov edx, dword [num1_hi+4]

sub eax, dword [num2_lo]
sbb ebx, dword [num2_lo+4]
sbb ecx, dword [num2_hi]
sbb edx, dword [num2_hi+4]
jb .overflow    ;or jc

गुणन

क्या बहुत मुश्किल है आपको दूसरे नंबर के प्रत्येक भाग के साथ fisrt संख्या के प्रत्येक भाग को गुणा करना होगा और परिणाम जोड़ें। आपको केवल दो उच्चतम भाग गुणा करने की ज़रूरत नहीं है जो निश्चित रूप से अतिप्रवाह होगा। स्यूडोकोड:

long long int /*128-bit*/ result = 0;
long long int n1 = ;
long long int n2 = ;
#define PART_WIDTH 32 //to be able to manipulate with numbers in 32-bit registers

int i_1 = 0; /*iteration index*/
for(each n-bit wide part of first number : n1_part) {
    int i_2 = 0;
    for(each n-bit wide part of second number : n2_part) {
        result += (n1_part << (i_1*PART_WIDTH))*(n2_part << (i_2*PART_WIDTH));
        i_2++;
    }
    i++;
}

विभाजन

और भी जटिल है उपयोगकर्ता ब्रेंडन ऑन ओसवीव.org फोरम ने उदाहरण के लिए सीड्यूडोड को एन-बिट इंटिजर्स के विभाजन के लिए पोस्ट किया । मैं इसे यहाँ पेस्ट कर रहा हूँ क्योंकि सिद्धांत एक ही है

result = 0;
count = 0;
remainder = numerator;

while(highest_bit_of_divisor_not_set) {
    divisor = divisor << 1;
    count++;
}
while(remainder != 0) {
    if(remainder >= divisor) {
        remainder = remainder - divisor;
        result = result | (1 << count);
    }
    if(count == 0) {
        break;
    }
    divisor = divisor >> 1;
    count--;
}






arbitrary-precision