【发布时间】:2012-10-02 13:17:37
【问题描述】:
我正在从单个字节中读取一些值。我在用户手册中被告知这一字节包含 3 个不同的值。有一个表格是这样的:
我解释这意味着精度占用 3 位,比例占用 2,大小占用 3,总共 8(1 个字节)。
我不清楚的是:
1 - 为什么它被标记为 7 到 0 而不是 0 到 7(可能与意义有关?)
2 - 如何从那个字节中提取单个值?
【问题讨论】:
标签: c#
我正在从单个字节中读取一些值。我在用户手册中被告知这一字节包含 3 个不同的值。有一个表格是这样的:
我解释这意味着精度占用 3 位,比例占用 2,大小占用 3,总共 8(1 个字节)。
我不清楚的是:
1 - 为什么它被标记为 7 到 0 而不是 0 到 7(可能与意义有关?)
2 - 如何从那个字节中提取单个值?
【问题讨论】:
标签: c#
习惯上根据它们的重要性对字节中的位进行编号:位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 输出:
【讨论】:
Potayto,potahto。
您可以使用移位和掩码来消除不需要的位,如下所示:
byte b = something; // b is our byte
int size = b & 0x7;
int scale = (b >> 3) & 0x3;
int position = (b >> 5) & 0x7;
【讨论】:
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;
重要提示:这假设单个值将被解释为正整数。如果这些值可能是负数,那么这将无法正常工作。鉴于您的变量名称,这不太可能成为问题。
【讨论】:
您可以通过按位算术来做到这一点:
uint precision = (thatByte & 0xe0) >> 5,
scale = (thatByte & 0x18) >> 3,
size = thatByte & 7;
【讨论】: