यहां एक एल्गोरिथ्म के दस्तावेज़ से लिंक किया गया है जो विज़ुअल स्टूडियो (ज्यादातर मामलों में) के साथ देखे जाने वाले मूल्यों और कोड का उत्पादन करता है और मुझे लगता है कि अभी भी जीसीसी में एक स्थिर पूर्णांक द्वारा एक चर पूर्णांक के विभाजन के लिए उपयोग किया जाता है।
http://gmplib.org/~tege/divcnst-pldi94.pdf
लेख में, एक तलवार के पास N बिट्स होते हैं, एक udword में 2N बिट्स, n = अंश = लाभांश, d = भाजक = भाजक होता है, initially शुरू में छत (log2 (d)) पर सेट किया जाता है, shpre प्री-शिफ्ट (गुणा करने से पहले उपयोग किया जाता है) ) = e = शून्य बिट्स को अनुगामी बनाने की संख्या, shpost पोस्ट-शिफ्ट (गुणा के बाद उपयोग किया जाता है), सटीक परिशुद्धता है = N - e = N - shpre। लक्ष्य पूर्व-पाली, गुणा और बाद की पाली का उपयोग करके n / d की गणना का अनुकूलन करना है।
6.2 नीचे स्क्रॉल करें, जो यह बताता है कि एक udword गुणक (अधिकतम आकार N + 1 बिट्स है), कैसे उत्पन्न होता है, लेकिन इस प्रक्रिया को स्पष्ट रूप से नहीं बताता है। मैं इसे नीचे समझाता हूँ।
चित्र ४.२ और आंकड़ा ६.२ यह दर्शाता है कि अधिकांश भाजक के लिए गुणक को N बिट या कम गुणक में कैसे घटाया जा सकता है। समीकरण 4.5 बताता है कि कैसे फॉर्मूला 4.1 और 4.2 में एन + 1 बिट मल्टीप्लायरों से निपटने के लिए इस्तेमाल किया गया था।
आधुनिक X86 और अन्य प्रोसेसर के मामले में, गुणा समय निश्चित है, इसलिए प्री-शिफ्ट इन प्रोसेसर पर मदद नहीं करता है, लेकिन यह अभी भी गुणक को N + 1 बिट से N बिट तक कम करने में मदद करता है। मुझे नहीं पता कि क्या GCC या Visual Studio ने X86 लक्ष्य के लिए पूर्व-शिफ्ट को समाप्त कर दिया है।
चित्रा 6.2 पर वापस जाना। Mlow और mhigh के लिए अंश (डिविडेंड) एक udword से बड़ा तभी हो सकता है जब भाजक (भाजक)> 2 ^ (N-1) (जब ℓ == N => mlow = 2 ^ (2N)), इस मामले में n / d के लिए अनुकूलित प्रतिस्थापन एक तुलना है (यदि n> = d, q = 1, अन्यथा q = 0), तो कोई गुणक उत्पन्न नहीं होता है। Mlow और mhigh के प्रारंभिक मान N + 1 बिट्स होंगे, और दो udword / uword डिवाइसेस का उपयोग प्रत्येक N + 1 बिट वैल्यू (mlow या mhigh) के उत्पादन के लिए किया जा सकता है। उदाहरण के रूप में 64 बिट मोड में X86 का उपयोग करना:
; upper 8 bytes of dividend = 2^(ℓ) = (upper part of 2^(N+ℓ))
; lower 8 bytes of dividend for mlow = 0
; lower 8 bytes of dividend for mhigh = 2^(N+ℓ-prec) = 2^(ℓ+shpre) = 2^(ℓ+e)
dividend dq 2 dup(?) ;16 byte dividend
divisor dq 1 dup(?) ; 8 byte divisor
; ...
mov rcx,divisor
mov rdx,0
mov rax,dividend+8 ;upper 8 bytes of dividend
div rcx ;after div, rax == 1
mov rax,dividend ;lower 8 bytes of dividend
div rcx
mov rdx,1 ;rdx:rax = N+1 bit value = 65 bit value
आप जीसीसी के साथ इसका परीक्षण कर सकते हैं। आप पहले से ही देख रहे हैं कि j = i / 5 कैसे संभाला जाता है। देखिए कैसे j = i / 7 को संभाला जाता है (जो कि N + 1 बिट गुणक केस होना चाहिए)।
अधिकांश वर्तमान प्रोसेसर पर, एक निश्चित समय में गुणा करना होता है, इसलिए प्री-शिफ्ट की आवश्यकता नहीं होती है। X86 के लिए, अंतिम परिणाम अधिकांश भाजक के लिए एक दो अनुदेश अनुक्रम है, और 7 (जैसे एक एन + 1 बिट गुणक का अनुकरण करने के लिए 5 के लिए पांच अनुदेश अनुक्रम अनुक्रम समीकरण 4.5 और पीडीएफ फाइल के आंकड़े 4.2 में दिखाया गया है)। उदाहरण X86-64 कोड:
; rax = dividend, rbx = 64 bit (or less) multiplier, rcx = post shift count
; two instruction sequence for most divisors:
mul rbx ;rdx = upper 64 bits of product
shr rdx,cl ;rdx = quotient
;
; five instruction sequence for divisors like 7
; to emulate 65 bit multiplier (rbx = lower 64 bits of multiplier)
mul rbx ;rdx = upper 64 bits of product
sub rbx,rdx ;rbx -= rdx
shr rbx,1 ;rbx >>= 1
add rdx,rbx ;rdx = upper 64 bits of corrected product
shr rdx,cl ;rdx = quotient
; ...