Grabbing n bits from a byte

后端 未结 6 2009
走了就别回头了
走了就别回头了 2021-01-30 14:31

I\'m having a little trouble grabbing n bits from a byte.

I have an unsigned integer. Let\'s say our number in hex is 0x2A, which is 42 in decimal. In binary it looks li

相关标签:
6条回答
  • 2021-01-30 15:24

    You could use bitfields for this. Bitfields are special structs where you can specify variables in bits.

    typedef struct {
      unsigned char a:5;
      unsigned char b:3;
    } my_bit_t;
    
    unsigned char c = 0x42;
    my_bit_t * n = &c;
    int first = n->a;
    int sec = n->b;
    

    Bit fields are described in more detail at http://www.cs.cf.ac.uk/Dave/C/node13.html#SECTION001320000000000000000

    The charm of bit fields is, that you do not have to deal with shift operators etc. The notation is quite easy. As always with manipulating bits there is a portability issue.

    0 讨论(0)
  • 2021-01-30 15:25

    "grabbing" parts of an integer type in C works like this:

    1. You shift the bits you want to the lowest position.
    2. You use & to mask the bits you want - ones means "copy this bit", zeros mean "ignore"

    So, in you example. Let's say we have a number int x = 42;

    first 5 bits:

    (x >> 3) & ((1 << 5)-1);
    

    or

    (x >> 3) & 31;
    

    To fetch the lower three bits:

    (x >> 0) & ((1 << 3)-1)
    

    or:

    x & 7;
    
    0 讨论(0)
  • 2021-01-30 15:27

    Integers are represented inside a machine as a sequence of bits; fortunately for us humans, programming languages provide a mechanism to show us these numbers in decimal (or hexadecimal), but that does not alter their internal representation.

    You should revise the bitwise operators &, |, ^ and ~ as well as the shift operators << and >>, which will help you understand how to solve problems like this.

    The last 3 bits of the integer are:

    x & 0x7
    

    The five bits starting from the eight-last bit are:

    x >> 3    // all but the last three bits
      &  0x1F // the last five bits.
    
    0 讨论(0)
  • 2021-01-30 15:28

    Say you want hi bits from the top, and lo bits from the bottom. (5 and 3 in your example)

    top = (n >> lo) & ((1 << hi) - 1)
    bottom = n & ((1 << lo) - 1)
    

    Explanation:

    For the top, first get rid of the lower bits (shift right), then mask the remaining with an "all ones" mask (if you have a binary number like 0010000, subtracting one results 0001111 - the same number of 1s as you had 0-s in the original number).

    For the bottom it's the same, just don't have to care with the initial shifting.

    top = (42 >> 3) & ((1 << 5) - 1) = 5 & (32 - 1) = 5 = 00101b
    bottom = 42 & ((1 << 3) - 1) = 42 & (8 - 1) = 2 = 010b
    
    0 讨论(0)
  • 2021-01-30 15:29

    int x = (number >> 3) & 0x1f;

    will give you an integer where the last 5 bits are the 8-4 bits of number and zeros in the other bits.

    Similarly,

    int y = number & 0x7;

    will give you an integer with the last 3 bits set the last 3 bits of number and the zeros in the rest.

    0 讨论(0)
  • 2021-01-30 15:33

    just get rid of the 8* in your code.

    int input = 42;
    int high3 = input >> 5;
    int low5 = input & (32 - 1); // 32 = 2^5
    bool isBit3On = input & 4; // 4 = 2^(3-1)
    
    0 讨论(0)
提交回复
热议问题