15

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

位表

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

我不清楚的是:

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

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

4

5 回答 5

20

习惯上按字节的意义对位进行编号:位x表示2^x。根据这种编号方案,最低有效位编号为零,下一位编号为 1,依此类推。

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

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

移动您需要获得的最右边部分的右边的位数(移动零被忽略;我添加它是为了便于说明)。

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

于 2012-10-02T13:23:01.433 回答
6

您可以进行转换和掩码,也可以使用 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 输出:

LINQPad 输出

于 2012-10-02T13:23:43.483 回答
5
  1. 波塔托,波塔托。

  2. 您将使用移位和掩码来展平不需要的位,如下所示:

    byte b = something; // b is our byte
    
    int size = b & 0x7;
    int scale = (b >> 3) & 0x3;
    int position = (b >> 5) & 0x7;
    
于 2012-10-02T13:21:21.293 回答
4

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

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

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

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

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

于 2012-10-02T13:20:13.820 回答
1

您可以通过按位算术执行此操作:

uint precision = (thatByte & 0xe0) >> 5,
    scale = (thatByte & 0x18) >> 3,
    size = thatByte & 7;
于 2012-10-02T13:21:50.400 回答