【问题标题】:C#, bits & bytes - How do I retrieve bit values from a byte?C#, bits & bytes - 如何从字节中检索位值?
【发布时间】:2012-10-02 13:17:37
【问题描述】:

我正在从单个字节中读取一些值。我在用户手册中被告知这一字节包含 3 个不同的值。有一个表格是这样的:

我解释这意味着精度占用 3 位,比例占用 2,大小占用 3,总共 8(1 个字节)。

我不清楚的是:

1 - 为什么它被标记为 7 到 0 而不是 0 到 7(可能与意义有关?)

2 - 如何从那个字节中提取单个值?

【问题讨论】:

    标签: c#


    【解决方案1】:

    习惯上根据它们的重要性对字节中的位进行编号:位x代表2^x。根据这种编号方案,最低有效位编号为零,下一位编号为 1,依此类推。

    获取单个位需要移位和屏蔽操作:

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

    按您需要获取的最右边部分的右侧移动位数(忽略零移位;出于说明目的,我添加了它)。

    具有适合您想要获得的位数的最大数字的掩码:1 表示一位,3 表示两位,7 表示三位,2^x-1 表示x 位。

    【讨论】:

    • 感谢您对掩码号如何工作的解释。
    • 用另一种方式尝试操作符: var size = ((v & 7) >> 0); var scale = ((v & 28) >> 3); var 精度 = ((v & 224) >> 5);
    【解决方案2】:

    您可以进行移位和掩码,也可以使用 BitArray 类:http://msdn.microsoft.com/en-us/library/system.collections.bitarray.aspx

    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 输出:

    【讨论】:

    • +1 用于指出不回溯到 C 时代的替代方案:P BitVector32 是另一种选择,它还允许您将位域分成多个部分(对应于 OP大小、比例和精度)并使用索引语法直接分配或读取它们中的每一个。
    【解决方案3】:
    1. Potayto,potahto。

    2. 您可以使用移位和掩码来消除不需要的位,如下所示:

      byte b = something; // b is our byte
      
      int size = b & 0x7;
      int scale = (b >> 3) & 0x3;
      int position = (b >> 5) & 0x7;
      

    【讨论】:

      【解决方案4】:

      1。是的,通常首先写入最高有效位。最左边的位标记为 7,因为当字节被解释为整数时,该位在设置时具有值 27 (= 128)。

      这是完全自然的,实际上与您编写十进制数的方式完全相同(最高有效位在前)。例如,数字 356 是 (3 x 102) + (5 x 101) + ( 6 x 100)。

      2。为了完成,如其他答案中所述,您可以使用位移位和按位与运算符提取各个值,如下所示:

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

      重要提示:这假设单个值将被解释为正整数。如果这些值可能是负数,那么这将无法正常工作。鉴于您的变量名称,这不太可能成为问题。

      【讨论】:

      • 我们每个人都回答了不同的问题。我们是否分开投票或其他什么? :D
      【解决方案5】:

      您可以通过按位算术来做到这一点:

      uint precision = (thatByte & 0xe0) >> 5,
          scale = (thatByte & 0x18) >> 3,
          size = thatByte & 7;
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2023-03-15
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2022-12-09
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多