C#, bits & bytes - How do I retrieve bit values from a byte?

前端 未结 5 1005
陌清茗
陌清茗 2020-12-29 08:04

I\'m reading some values from a single byte. I\'m told in the user-manual that this one byte contains 3 different values. There\'s a table that looks like this:

相关标签:
5条回答
  • 2020-12-29 08:24

    It is customary to number bits in a byte according to their significance: bit x represents 2^x. According to this numbering scheme, the least significant bit gets number zero, the next bit is number one, and so on.

    Getting individual bits requires a shift and a masking operation:

    var size = (v >> 0) & 7;
    var scale = (v >> 3) & 3;
    var precision = (v >> 5) & 7;
    

    Shift by the number of bits to the right of the rightmost portion that you need to get (shifting by zero is ignored; I added it for illustration purposes).

    Mask with the highest number that fits in the number of bits that you would like to get: 1 for one bit, 3 for two bits, 7 for three bits, 2^x-1 for x bits.

    0 讨论(0)
  • 2020-12-29 08:24

    You can do this via bitwise arithmetic:

    uint precision = (thatByte & 0xe0) >> 5,
        scale = (thatByte & 0x18) >> 3,
        size = thatByte & 7;
    
    0 讨论(0)
  • 2020-12-29 08:37

    You can do shifts and masks, or you can use the BitArray class: http://msdn.microsoft.com/en-us/library/system.collections.bitarray.aspx

    Example with BitVector32:

    BitVector32 bv = new BitVector32(0);
    
    var size = BitVector32.CreateSection(7);
    var scale = BitVector32.CreateSection(3, size);
    var precision = BitVector32.CreateSection(7, scale);
    
    bv[size] = 5;
    bv[scale] = 2;
    bv[precision] = 4;
    

    LINQPad output:

    LINQPad output

    0 讨论(0)
  • 2020-12-29 08:38
    1. Potayto, potahto.

    2. You'd use shifts and masks to flatten out the undesired bits, like such:

      byte b = something; // b is our byte
      
      int size = b & 0x7;
      int scale = (b >> 3) & 0x3;
      int position = (b >> 5) & 0x7;
      
    0 讨论(0)
  • 2020-12-29 08:46

    1. Yes, the most significant bit is usually written first. The left-most bit is labeled 7 because when the byte is interpreted as an integer, that bit has value 27 (= 128) when it is set.

    This is completely natural and is in fact is exactly the same as how you write decimal numbers (most significant digit first). For example, the number 356 is (3 x 102) + (5 x 101) + (6 x 100).

    2. For completion, as mentioned in other answers you can extract the individual values using the bit shift and bitwise-and operators as follows:

    int size = x & 7;
    int scale = (x >> 3) & 3;
    int precision = (x >> 5) & 7;
    

    Important note: this assumes that the individual values are to be interpreted as positive integers. If the values could be negative then this won't work correctly. Given the names of your variables, this is unlikely to be a problem here.

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