एक कुशल Microsoft (जैसे, Visual Studio 2017) पूर्णांक इनपुट के लिए C / C ++ में विशिष्ट समाधान। इनपुट के मामले को सबसे महत्वपूर्ण 1 बिट के स्थान की जांच करने से पहले दो मूल्य की शक्ति के मिलान से घटाकर नियंत्रित करता है।
inline unsigned int ExpandToPowerOf2(unsigned int Value)
{
unsigned long Index;
_BitScanReverse(&Index, Value - 1);
return (1U << (Index + 1));
}
// - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
#if defined(WIN64) // The _BitScanReverse64 intrinsic is only available for 64 bit builds because it depends on x64
inline unsigned long long ExpandToPowerOf2(unsigned long long Value)
{
unsigned long Index;
_BitScanReverse64(&Index, Value - 1);
return (1ULL << (Index + 1));
}
#endif
यह निम्नलिखित के समान इंटेल प्रोसेसर के लिए 5 या तो इनलाइन निर्देश उत्पन्न करता है:
dec eax
bsr rcx, rax
inc ecx
mov eax, 1
shl rax, cl
जाहिरा तौर पर विजुअल स्टूडियो सी ++ कंपाइलर को संकलन-समय मूल्यों के लिए इसे अनुकूलित करने के लिए कोडित नहीं किया गया है, लेकिन ऐसा नहीं है कि वहां बहुत सारे निर्देश हैं।
संपादित करें:
यदि आप 1 से 1 (2 से शून्य शक्ति) का इनपुट मान चाहते हैं, तो उपरोक्त कोड के लिए एक छोटा संशोधन अभी भी बिना किसी शाखा के निर्देशों के सीधे उत्पन्न होता है।
inline unsigned int ExpandToPowerOf2(unsigned int Value)
{
unsigned long Index;
_BitScanReverse(&Index, --Value);
if (Value == 0)
Index = (unsigned long) -1;
return (1U << (Index + 1));
}
केवल कुछ और निर्देश उत्पन्न करता है। चाल यह है कि सूचकांक को एक परीक्षण द्वारा प्रतिस्थापित किया जा सकता है जिसके बाद एक cmove निर्देश दिया जाता है।