我正在从一个字节中读取一些值。我在用户手册中被告知这一字节包含 3 个不同的值。有一个看起来像这样的表:
我解释这意味着精度占用 3 位,比例占用 2,大小占用 3,总共 8(1 个字节)。
我不清楚的是:
1 - 为什么它被标记为 7 到 0 而不是 0 到 7 (可能与意义有关?)
2 - 如何从那个字节中提取单个值?
我正在从一个字节中读取一些值。我在用户手册中被告知这一字节包含 3 个不同的值。有一个看起来像这样的表:
我解释这意味着精度占用 3 位,比例占用 2,大小占用 3,总共 8(1 个字节)。
我不清楚的是:
1 - 为什么它被标记为 7 到 0 而不是 0 到 7 (可能与意义有关?)
2 - 如何从那个字节中提取单个值?
习惯上按字节的意义对位进行编号:位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
。
您可以进行转换和掩码,也可以使用 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 输出:
波塔托,波塔托。
您将使用移位和掩码来展平不需要的位,如下所示:
byte b = something; // b is our byte
int size = b & 0x7;
int scale = (b >> 3) & 0x3;
int position = (b >> 5) & 0x7;
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;
重要说明:这假设各个值将被解释为正整数。如果这些值可能是负数,那么这将无法正常工作。鉴于变量的名称,这在这里不太可能成为问题。
您可以通过按位算术执行此操作:
uint precision = (thatByte & 0xe0) >> 5,
scale = (thatByte & 0x18) >> 3,
size = thatByte & 7;