kdb*_*las 8 c bit-manipulation
我想当我们谈到比特位置时,我可能已经在我的CS课上睡着了,所以我希望有人能伸出援助之手.
我有一个无符号的32位整数(让我们使用值:28)
根据我要讨论的一些文档,整数的值包含指定各种内容的标志.
标志内的位位置从1(低位)到32(高位)编号.所有未定义的标志位都是保留的,必须设置为0.
我有一个表格,显示标志的含义,数字1-10的含义.
我希望有人可以尝试向我解释这一切意味着什么,以及如何根据比特位置从数字28中找到"标志"值.
谢谢
Jer*_*fin 12
28以二进制形式转换为11100.这意味着未设置位1和2,并设置位3,4和5.
几点:首先,任何真正习惯于C的人通常都会将编号从0开始,而不是1.其次,您可以使用按位和运算符(&)来测试各个标志,如下所示:
#define flag1 1 // 1 = 00 0001
#define flag2 2 // 2 = 00 0010
#define flag3 4 // 4 = 00 0100
#define flag4 8 // 8 = 00 1000
#define flag5 16 // 16 = 01 0000
#define flag6 32 // 32 = 10 0000
if (myvalue & flag1)
// flag1 was set
if (myvalue & flag4)
// flag4 was set
Run Code Online (Sandbox Code Playgroud)
等等.您还可以检查循环中设置的位:
#include <stdio.h>
int main() {
int myvalue = 28;
int i, iter;
for (i=1, iter=1; i<256; i<<=1, iter++)
if (myvalue & i)
printf("Flag: %d set\n", iter);
return 0;
}
Run Code Online (Sandbox Code Playgroud)
应该打印:
Flag: 3 set
Flag: 4 set
Flag: 5 set
Run Code Online (Sandbox Code Playgroud)
小智 9
您可以改为仅循环设置位,而不是循环遍历每个位,如果您希望稀疏地设置位,则可以更快:
假设位字段在(标量整数)变量字段中.
while (field){
temp = field & -field; //extract least significant bit on a 2s complement machine
field ^= temp; // toggle the bit off
//now you could have a switch statement or bunch of conditionals to test temp
//or get the index of the bit and index into a jump table, etc.
}
Run Code Online (Sandbox Code Playgroud)
当位字段不限于单个数据类型的大小时,可以很好地工作,但可以是任意大小.在这种情况下,您可以一次提取32(或任何您的寄存器大小)位,对0进行测试,然后继续下一个字.
要获取int包含该值0或1仅表示n该整数的第 th 位的 ,请使用:
int bitN = (value >> n) & 1;
Run Code Online (Sandbox Code Playgroud)
但这通常不是您想要做的。一个更常见的习语是这样的:
int bitN = value & (1 << n);
Run Code Online (Sandbox Code Playgroud)
在这种情况下,bitN如果0第nth 位未设置,则为非零,如果n设置了第 th 位,则为非零。(具体来说,它将是仅设置第 th 位后得出的任何值n。)