2013-09-03 12 views
36

मैं इसे C++ में कैसे उपयोग करूं? उपयोग करने में उपयोगी कब है?
कृपया मुझे एक समस्या का उदाहरण दें जहां बिटकमास्क का उपयोग किया जाता है, यह वास्तव में कैसे काम करता है। धन्यवाद!बिटमैस्क का उपयोग कैसे करें?

+2

क्या आपके पास सी ++ 11 है? और std :: बिटसेट? – dzada

+0

'std :: ios_base :: fmtflags'। –

+4

https://www.google.com/search?q=what+is+a+bitmask – LarryPel

उत्तर

19

बिट मास्किंग जब आप एक डेटा मूल्य के भीतर अलग-अलग डेटा स्टोर करना चाहते हैं (और बाद में निकालने) का उपयोग करने के लिए "उपयोगी" है।

एक उदाहरण एप्लिकेशन जो मैंने पहले उपयोग किया है, कल्पना है कि आप 16 बिट मान में रंग आरजीबी मान संग्रहीत कर रहे थे। तो कुछ है कि इस तरह दिखता है:

RRRR RGGG GGGB BBBB 

फिर आप इस प्रकार रंग घटकों को पुनः प्राप्त करने मास्किंग सा इस्तेमाल कर सकते हैं:

const unsigned short redMask = 0xF800; 
    const unsigned short greenMask = 0x07E0; 
    const unsigned short blueMask = 0x001F; 

    unsigned short lightGray = 0x7BEF; 

    unsigned short redComponent = (lightGray & redMask) >> 11; 
    unsigned short greenComponent = (lightGray & greenMask) >> 5; 
    unsigned short blueComponent = (lightGray & blueMask); 
+1

का समर्थन करता है, मुझे यह समझ में नहीं आता है, आप कह रहे हैं कि 0xF800 मूल रूप से बिट्स का एक समूह है जिसे वह चुन रहा है (उर्फ यह उन बिट्स को बाइट्स के सेट समूह से पते से निकाल रहा है)? मैंने सोचा कि बिटमैस्क मूल रूप से डेटा के समान आकार का एक int था (इसलिए इस मामले में यह 48 बिट्स होगा) और मुखौटा ओवरटॉप लागू किया गया था, जब मास्क के मान 1 अंतर्निहित बिट का मूल्य दिखाता है, और जब यह शून्य हो, तो यह आपको ऑफ बिट्स को अनदेखा करने की इजाजत नहीं देता है? और किसके लिए स्थानांतरित हो रहा है? – MarcusJ

+0

@MarcusJ: कृपया नीचे goGud द्वारा उदाहरण देखें, जो बिटमैस्क पर अधिक जानकारी प्रदान करता है (यानी http://stackoverflow.com/questions/18591924/how-to-use-bitmask/18592049#18592049) – a505999

+0

मैं एक हूँ बेवकूफ। मुझे पता था कि बिटमैस्किंग क्या थी, लेकिन मुझे एहसास नहीं हुआ कि आरजीबी ट्रिपल 8 बिट्स नहीं था, जिससे मेरा भ्रम पैदा हुआ। फ़िर भी सहायता के लिए धन्यवाद! :) – MarcusJ

93

संक्षेप bitmask से अधिक मान की स्थिति में हेरफेर करने में मदद करता है। यहां एक अच्छा उदाहरण है;

बिटफ्लैग एक चर में एकाधिक मूल्यों को संग्रहीत करने का एक तरीका है, जो पारस्परिक रूप से अनन्य नहीं हैं। आपने शायद उन्हें पहले देखा है। प्रत्येक झंडा एक बिट स्थिति है जिसे सेट या बंद किया जा सकता है। इसके बाद आप प्रत्येक बिट स्थिति के लिए #defined bitmasks का एक समूह है ताकि आप आसानी से यह हेरफेर कर सकते हैं:

#define LOG_ERRORS   1 // 2^0, bit 0 
    #define LOG_WARNINGS   2 // 2^1, bit 1 
    #define LOG_NOTICES   4 // 2^2, bit 2 
    #define LOG_INCOMING   8 // 2^3, bit 3 
    #define LOG_OUTGOING   16 // 2^4, bit 4 
    #define LOG_LOOPBACK   32 // and so on... 

// Only 6 flags/bits used, so a char is fine 
unsigned char flags; 

// initialising the flags 
// note that assignming a value will clobber any other flags, so you 
// should generally only use the = operator when initialising vars. 
flags = LOG_ERRORS; 
// sets to 1 i.e. bit 0 

//initialising to multiple values with OR (|) 
flags = LOG_ERRORS | LOG_WARNINGS | LOG_INCOMING; 
// sets to 1 + 2 + 8 i.e. bits 0, 1 and 3 

// setting one flag on, leaving the rest untouched 
// OR bitmask with the current value 
flags |= LOG_INCOMING; 

// testing for a flag 
// AND with the bitmask before testing with == 
if ((flags & LOG_WARNINGS) == LOG_WARNINGS) 
    ... 

// testing for multiple flags 
// as above, OR the bitmasks 
if ((flags & (LOG_INCOMING | LOG_OUTGOING)) 
     == (LOG_INCOMING | LOG_OUTGOING)) 
    ... 

// removing a flag, leaving the rest untouched 
// AND with the inverse (NOT) of the bitmask 
flags &= ~LOG_OUTGOING; 

// toggling a flag, leaving the rest untouched 
flags ^= LOG_LOOPBACK; 



** 

चेतावनी: परीक्षण एक झंडा अगर के लिए समानता ऑपरेटर का उपयोग नहीं करते (यानी bitflags == bitmask) सेट है - यह अभिव्यक्ति केवल तभी सच होगी यदि कि ध्वज सेट है और अन्य सभी अनसेट हैं। एक भी झंडा आप & और == उपयोग करने की आवश्यकता के लिए परीक्षण करने के लिए:

**

if (flags == LOG_WARNINGS) //DON'T DO THIS 
    ... 
if ((flags & LOG_WARNINGS) == LOG_WARNINGS) // The right way 
    ... 
if ((flags & (LOG_INCOMING | LOG_OUTGOING)) // Test for multiple flags set 
     == (LOG_INCOMING | LOG_OUTGOING)) 
    ... 

तुम भी खोज C++ Triks

+0

बिटफ्लैग के बारे में आपके उदाहरण में, यह कैसे पता चलता है कि कौन सा बिट किस चर से संबंधित है? बाइट में यह स्थिति है, या बाइट का वास्तविक मूल्य कुछ विशेषताओं को चालू और बंद करता है? – MarcusJ

3

चलो कहते हैं कि मैं के साथ 32-बिट ARGB मूल्य करते हैं कर सकते हैं प्रति चैनल 8-बिट्स। मैं एक अल्फा मूल्य के साथ अल्फा घटक बदलना चाहते हैं, इस तरह के रूप 0x45

unsigned long alpha = 0x45 
unsigned long pixel = 0x12345678; 
pixel = ((pixel & 0x00FFFFFF) | (alpha << 24)); 

मुखौटा 0, जहां वर्ष अल्फा मूल्य था करने के लिए शीर्ष 8 बिट बदल जाता है। अल्फा मान को अंतिम बिट पोजिशन में ले जाया जाएगा, फिर यह मुखौटा पिक्सेल मान में OR-ed होगा। अंतिम परिणाम 0x45345678 है जो पिक्सेल में संग्रहीत है।

3

बिटमैस्क का उपयोग तब किया जाता है जब आप एक ही संख्या में जानकारी की कई परतों को एन्कोड करना चाहते हैं।

तो (यूनिक्स फ़ाइल अनुमतियां मानते हुए) यदि आप एक्सेस प्रतिबंध के 3 स्तरों को संग्रहीत करना चाहते हैं (पढ़ें, लिखें, निष्पादित करें) तो आप संबंधित बिट को चेक करके प्रत्येक स्तर की जांच कर सकते हैं।

rwx 
--- 
110 

110 आधार 2 में आधार में 6 से 10 करने के लिए अनुवाद

तो आप आसानी से देख सकते हैं कि किसी को अनुमति दी है जैसे वांछित अनुमति के साथ अनुमति फ़ील्ड द्वारा फ़ाइल को पढ़ना और पढ़ना।

स्यूडोकोड:

PERM_READ = 4 
PERM_WRITE = 2 
PERM_EXEC = 1 

user_permissions = 6 

if (user_permissions & PERM_READ == TRUE) then 
    // this will be reached, as 6 & 4 is true 
fi 

आप संख्या और तार्किक ऑपरेटरों के द्विआधारी प्रतिनिधित्व के एक काम समझ की जरूरत है बिट क्षेत्रों को समझने के लिए।

+0

हालांकि 6 और 4 सच क्यों है? वास्तव में क्या गणितीय ऑपरेशन हो रहा है? – MarcusJ

+1

एक द्विआधारी संख्या या तो 0 या 1. 4 है '100', 6' 110' है। _and_ संख्याओं के लिए, _and_ प्रत्येक बाइनरी अंक। –

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