2012-01-19 5 views
17

में सेट किया गया है, तो मुझे एक साधारण सी फ़ंक्शन चाहिए जो एक बाइट में n-th बिट 1 पर सेट होने पर सत्य वापस आ जाएगा। अन्यथा यह झूठी वापसी होगी।यह जांचने के लिए एक फ़ंक्शन है कि nth बिट को बाइट

निष्पादन समय के मामले में यह एक महत्वपूर्ण कार्य है, इसलिए मैं ऐसा करने का सबसे इष्टतम तरीका सोच रहा हूं।

+1

डुप्लिकेट, http://stackoverflow.com/questions/523724/cc-check-if-one-bit-is -set-in-ie-int-variable – blueshift

+4

यह एक डुप्ली नहीं है, यह विशेष रूप से ** गैर-बिट्सफ़िफ़्ट ** विधियों के बारे में पूछा गया है। – paxdiablo

उत्तर

32

निम्नलिखित समारोह आपको क्या चाहिए कर सकते हैं:

int isNthBitSet (unsigned char c, int n) { 
    static unsigned char mask[] = {128, 64, 32, 16, 8, 4, 2, 1}; 
    return ((c & mask[n]) != 0); 
} 

यह 8 बिट बाइट मान लिया गया है (एक सी में नहीं दिया) और zeroth बिट सर्वोच्च क्रम से एक होने के। यदि उन धारणाएं गलत हैं, तो यह mask सरणी का विस्तार और/या फिर से ऑर्डर करने के लिए नीचे आती है।

कोई त्रुटि जांच नहीं की गई है क्योंकि आपने गति को सबसे महत्वपूर्ण विचार के रूप में उद्धृत किया है। एक अवैध n में पास करें, जो अपरिभाषित व्यवहार होगा।

पागल अनुकूलन स्तर -O3 में जीसीसी हमें देता है:

isNthBitSet: pushl %ebp 
       movl %esp, %ebp 
       movl 12(%ebp), %eax 
       movzbl 8(%ebp), %edx 
       popl %ebp 
       testb %dl, mask(%eax) 
       setne %al 
       movzbl %al, %eax 
       ret 
mask:   .byte -128, 64, 32, 16, 8, 4, 2, 1 

जो बहुत छोटे और कुशल है। और यदि आप इसे स्थिर बनाते हैं और इनलाइनिंग का सुझाव देते हैं, या इसे मैक्रो परिभाषा के रूप में इनलाइन करते हैं, तो आप फ़ंक्शन कॉल की लागत को भी बाईपास कर सकते हैं।

बस यह सुनिश्चित करें कि आप दिए गए किसी भी समाधान को बेंचमार्क करें, जिसमें (ए) शामिल है। अनुकूलन में नंबर एक मंत्र है "मापें, अनुमान न करें!"

यदि आप जानना चाहते हैं कि बिटवाई ऑपरेटरों कैसे काम करते हैं, तो here देखें। सरलीकृत और केवल संस्करण नीचे है।

और ऑपरेशन & केवल लक्ष्य में थोड़ा सा सेट करेगा यदि दोनों बिट्स tewo स्रोतों में सेट हैं। प्रासंगिक तालिका है:

AND | 0 1 
----+---- 
0 | 0 0 
1 | 0 1 

एक दिया char मूल्य के लिए, हम अगर एक सा सेट किया गया है की जाँच करने के एकल बिट बिट मास्क का उपयोग करें। मान लीजिए कि आपके पास मूल्य 13 है और आप देखना चाहते हैं कि तीसरा-से-कम-महत्वपूर्ण-बिट बिट सेट है या नहीं।

Decimal Binary 
    13  0000 1101 
    4  0000 0100 (the bitmask for the third-from-least bit). 
     ========= 
     0000 0100 (the result of the AND operation). 

आप देख सकते हैं कि मास्क में सभी शून्य बिट्स परिणामस्वरूप बराबर परिणाम बिट्स शून्य होते हैं। मुखौटा में एक ही बिट मूल रूप से परिणाम प्रवाह के माध्यम से मूल्य प्रवाह में बराबर बिट दे देगा। नतीजा तब शून्य होता है जब हम जो बिट जांच रहे हैं वह शून्य था, या गैर-शून्य अगर यह एक था।

यही वह जगह है जहां return कथन में अभिव्यक्ति आती है। mask लुकअप तालिका में मानों सभी एकल बिट मास्क हैं:

Decimal Binary 
    128 1000 0000 
    64 0100 0000 
    32 0010 0000 
    16 0001 0000 
    8 0000 1000 
    4 0000 0100 
    2 0000 0010 
    1 0000 0001 

(क)मैं जानता हूँ कि मैं कितना अच्छा कर रहा हूँ, लेकिन आप

+2

लुकअप टेबल, हाँ! लेकिन मैं बाइट में बिट 0 कम से कम महत्वपूर्ण बिट होने की अपेक्षा करता हूं, और इसलिए 'मास्क []' इंटिलाइज्ड प्रविष्टियों के क्रम को उलट दिया होगा। – hardmath

+0

हमेशा नहीं, @ हार्दमाथ, बहुत सारे कॉमम्स मानक "बाएं" से अपने ऑक्टेट भरते हैं। आप की तरह, मैं कम से कम महत्वपूर्ण के रूप में बी 0 के बारे में सोचना पसंद करता हूं। – paxdiablo

+0

-1, लिखने के लिए वर्बोज़ और त्रुटि-प्रवण, बिट स्थानांतरण के बारे में जानें। – blueshift

20
नहीं है :-)

बस (1 << bit) & byte का मूल्य देखें। यदि यह nonzero है, बिट सेट है।

3
bool isSet(unsigned char b, unsigned char n) { return b & (1 << n); } 
+0

मैं बाइट मान के लिए 'हस्ताक्षरित char' समझता हूं, लेकिन 'n'? यह अजीब लगता है। – Rob

+0

अच्छी तरह से एक बाइट से बड़ा नहीं हो सकता है ... यह वास्तव में –

+0

से अधिक मायने रखता नहीं है क्योंकि 'हस्ताक्षरित char' केवल मान्य मानों के लिए n को बाध्य नहीं करता है, इसलिए मैं तर्क दूंगा कि यह एक [छोटा] "कोड गंध" है पठनीयता के लिए। बेशक, यह बहस योग्य है और मैं सहमत हूं कि इससे कोई फर्क नहीं पड़ता। – Rob

8

संख्या num होने दें। तब:

return ((1 << n) & num); 
+0

क्या आप इस कोड को समझा सकते हैं? – vidyasagarr7

2
#include<stdio.h> 
int main() 
{ 
    unsigned int n,a; 
    printf("enter value for n\n"); 
    scanf("%u",&n); 
    pintf("enter value for a:\n"); 
    scanf("%u",&a); 
    a= a|(((~((unsigned)0))>>(sizeof(int)*8-1))<<n); 
    printf("%u\n",a); 
} 
2

एक और दृष्टिकोण होगा

bool isNthBitSet (unsigned char c, int n) { 
     return (1 & (c >> n)); 
    } 
0
#include<stdio.h> 

int main() 
{ 
     int data,bit; 
     printf("enter data:"); 
     scanf("%d",&data); 
     printf("enter bit position to test:"); 
     scanf("%d",&bit); 
     data&(1<<bit)?printf("bit is set\n"):printf("bit is clear\n"); 

    return 0; 
} 
+2

इस कोड-केवल-उत्तर को अतिरिक्त मूल्य को और अधिक स्पष्ट करने के लिए कुछ स्पष्टीकरण की आवश्यकता है, अन्य, पुराने, अपरिवर्तित और अधिकतर बेहतर समझाए गए उत्तरों की तुलना में (यह नहीं दर्शाता कि अन्य सभी उत्तरों बेहतर समझाए गए हैं ...)। – Yunnosch

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