首先,我想知道这是否可行:假设我有一个无符号长整数,其中包含一些无用的无符号短路,这些短路可能在数字中,也可能不在数字中。例如:
unsigned short int id1 = 3456,
id2 = 30998;
unsigned long long bitfld = id1|id2;
其他2个字段可以假定为0吗? OR是正确的操作吗?在那之后让我们说我将bitfld作为一个参数传递:
void dostuff (unsigned long long bf)
{
//pseudo code
if( the first field exists in bf)
get first field;
if( the second field exists in bf)
get second field;
//etc...
}
我想我必须查出位域的前16位并检查它们,然后递归轮询它们,验证它们并存储它们是否大于0.但我不知道如何做到这一点,位移位只是向左或向右移动,因此,它只能分开或相乘吗?
谢谢大家的回答。
答案 0 :(得分:4)
short int
长度为2个字节,但long long
为8个字节,因此您有某种长度不匹配的情况;
你可能意味着这个:
unsigned long long bitfld = id1|(id2<<16);
你可以检查AND
是否有一个字段占用它:
void dostuff (unsigned long long bf)
{
//pseudo code
if(bf & 0xFFFF)
return bf & 0xFFFF;
if(bf & 0xFF00)
return (bf & 0xFFFF0000) >> 32;
//etc...
}
答案 1 :(得分:2)
按位OR运算不是您想要的。该操作将合并现有位与新位。您需要一个替换位的操作。
首先,您需要使用AND和NOT来清除这些位:
unsigned short int id1 = 3456,
id2 = 30998;
unsigned long long bitfld;
unsigned short int all_ones = ~0;
const unsigned int id2_position = 1;
const unsigned int bits_to_shift_left = id2_position * sizeof(unsigned short) * CHAR_BIT;
unsigned long long mask = ~(all_ones << bits_to_shift_left);
bitfld = bitfld & mask; // Erase all bits in id2 position
bitfld = bitfld | (id2 << bits_to_shift_left); // Put value into second position.
除非缺少内存空间是一个问题,否则这种打包工作不值得开发,验证时间和额外的执行时间。将值放入unsigned char的“packed”缓冲区中,然后将缓冲区与I / O一起使用。
答案 2 :(得分:1)
您可能应该查看bitshift运算符及其工作原理。如果您只是执行:
id1 | id2
,您基本上将所有位混合在一起。您将无法在以后单独提取这些值。您想要做的是像用户alemjerus所指出的那样id1 | (id2 << 16)
。
实现相同目标的另一种方法是使用联合:
struct s_btfld {
unsigned short int f1;
unsigned short int f2;
unsigned short int f3;
unsigned short int f4;
};
union u_btfld {
struct s_btfld fields;
unsigned long long value;
};
现在你可以做到:
unsigned short int id1 = 3456, id2 = 30998;
union u_btfld bitfld;
bitfld.fields.f1 = id1;
bitfld.fields.f2 = id2;
dostuff(bitfld.value);
在dostuff中,您可以通过以下方式轻松检索字段:
void dostuff(unsigned long long bf) {
union u_btfld a;
a.value = bf;
printf("id1 = %d\n", a.fields.f1);
printf("id2 = %d\n", a.fields.f2);
}
答案 3 :(得分:0)
假设unsigned short是2个字节而unsigned long是4个字节。
unsigned short id1 = 0x0d80; //3456 decimal
unsigned short id2 = 0x7916; //30998 decimal
unsigned long bitfld = ((id2<<16)|id1) //id2<<16 = 0x79160000, so bitfld = 0x79160d80
if ((bitfld & id1) == id1) {
//id1 is in lower 2 bytes of bitfld
}
if ((bitfld>>16) &id2) == id2) { //bitfld>>16 = 0x00007916
//id2 is in upper 2 bytes of bitfld
}
这有帮助吗? 处理位时,如果使用十六进制值,则可以更直观地查看发生的情况。