C 在大小异常的单词上使用掩码
我正在编写一些代码,需要对56位(7字节)字和112位(14字节)字进行编码/解码 我习惯于处理32位字。如果我需要从一个单词中提取第23-25位,我只需这样做:C 在大小异常的单词上使用掩码,c,bitwise-operators,C,Bitwise Operators,我正在编写一些代码,需要对56位(7字节)字和112位(14字节)字进行编码/解码 我习惯于处理32位字。如果我需要从一个单词中提取第23-25位,我只需这样做: int unpackBits23To25( uint32_t word ) { return (word>>22) & 0x7; } 或者以更一般的方式,如: int unpackBits( uint8_t word[14], int startbit, int endbit ) { int mask
int unpackBits23To25( uint32_t word )
{
return (word>>22) & 0x7;
}
或者以更一般的方式,如:
int unpackBits( uint8_t word[14], int startbit, int endbit )
{
int mask = (0x1 << (endbit - startbit + 1)) - 1;
return (word >> (startbit - 1)) & mask;
}
这并不难写,但如果你想阅读/排除故障,它是完全难以辨认的。我还没有尝试过通用的解决方案,但我有一种感觉,它将是一个怪物
您建议如何对不清楚的字长执行逐位操作?这里有一种从被视为位数组的字节数组中提取单个位的通用方法:
uint8_t value = (word[bit/8] & (1 << (bit%8)) != 0;
uint8\u t value=(字[bit/8]&(1=startbit;i--){
uint8_t value=(word[i/8U]&(1此处不需要魔法。如果位操作影响所有字节(如移位),则必须迭代所有字节,并手动传播边界位。难道没有uint64_t
可用吗?@Peri461移位(和其他按位)运算符在非整数类型上未定义。请填充到合理的大小。如果编译器提供,112位适合unsigned\uu int128
,否则请使用2uint64\u t
。我不想在这里使用uint8\u t
,为什么元素比需要的多…@FelixPalmen:除非您必须处理尾数问题。然后它就可以了可以说使用uint8\u t[]
.Wow,这比预期的要容易。次要:开始位、结束位的负值是一个问题,可能会导致i/8、i%8
的代码效率较低,与始终有效的无符号div/rem 8相比,它可能会发出有符号除法/余数。可以使用无符号
位值和/或8u
而不是8
@chux在除数上使用u
后缀可能是一种方法。在这种情况下使用无符号的问题是因为我们在倒计时而不是向上。如果我们使用无符号值并且startbit
为0,则比较总是正确的,并且我们有一个无限循环。
uint8_t value = (word[bit/8] & (1 << (bit%8)) != 0;
uint32_t unpackBits( uint8_t word[14], int startbit, int endbit )
{
uint32_t result;
int i;
for (result = 0, i = endbit; i >= startbit; i--) {
uint8_t value = (word[i/8U] & (1 << (i%8U)) != 0;
result = (result << 1) | value;
}
return result;
}