How to use bitmask?

后端 未结 4 993
無奈伤痛
無奈伤痛 2020-12-04 06:35

How do i use it in C++ ? when is it useful to use ?
Please give me an example of a problem where bitmask is used , how it actually works . Thanks!

相关标签:
4条回答
  • 2020-12-04 07:02

    Bit masking is "useful" to use when you want to store (and subsequently extract) different data within a single data value.

    An example application I've used before is imagine you were storing colour RGB values in a 16 bit value. So something that looks like this:

    RRRR RGGG GGGB BBBB
    

    You could then use bit masking to retrieve the colour components as follows:

      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);
    
    0 讨论(0)
  • 2020-12-04 07:02

    Briefly bitmask helps to manipulate position of multiple values. There is a good example here ;

    Bitflags are a method of storing multiple values, which are not mutually exclusive, in one variable. You've probably seen them before. Each flag is a bit position which can be set on or off. You then have a bunch of bitmasks #defined for each bit position so you can easily manipulate it:

        #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 assigning 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;
    
    
    
    **
    

    WARNING: DO NOT use the equality operator (i.e. bitflags == bitmask) for testing if a flag is set - that expression will only be true if that flag is set and all others are unset. To test for a single flag you need to use & and == :

    **

    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))
       ...
    

    You can also search C++ Triks

    0 讨论(0)
  • 2020-12-04 07:05

    Let's say I have 32-bit ARGB value with 8-bits per channel. I want to replace the alpha component with another alpha value, such as 0x45

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

    The mask turns the top 8 bits to 0, where the old alpha value was. The alpha value is shifted up to the final bit positions it will take, then it is OR-ed into the masked pixel value. The final result is 0x45345678 which is stored into pixel.

    0 讨论(0)
  • 2020-12-04 07:06

    Bitmasks are used when you want to encode multiple layers of information in a single number.

    So (assuming unix file permissions) if you want to store 3 levels of access restriction (read, write, execute) you could check for each level by checking the corresponding bit.

    rwx
    ---
    110
    

    110 in base 2 translates to 6 in base 10.

    So you can easily check if someone is allowed to e.g. read the file by and'ing the permission field with the wanted permission.

    Pseudocode:

    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
    

    You need a working understanding of binary representation of numbers and logical operators to understand bit fields.

    0 讨论(0)
提交回复
热议问题