可能的重复:
查找 C 中的最高位
如何编写一个 C 函数来生成一个掩码,1
指示x
.
例如:0xFF00 -> 0x8000
和0x6600 -> 0x4000
。至今:
int left1(unsigned x){}
我明白,0xFF00 == 1111 1111 0000 0000..
但0x6600 == 0110 0110 0000 0000..
在那之后我很难过。
可能的重复:
查找 C 中的最高位
如何编写一个 C 函数来生成一个掩码,1
指示x
.
例如:0xFF00 -> 0x8000
和0x6600 -> 0x4000
。至今:
int left1(unsigned x){}
我明白,0xFF00 == 1111 1111 0000 0000..
但0x6600 == 0110 0110 0000 0000..
在那之后我很难过。
您可以分两部分执行此操作:首先,使用一种称为“位涂抹”的技术来确保第一个 1 右侧的所有位也是 1:
x |= x >> 16;
x |= x >> 8;
x |= x >> 4;
x |= x >> 2;
x |= x >> 1;
此时, 的输入0xFF00
将x
等于0xFFFF
, 的输入0x6600
将x
等于0x7FFF
。然后,我们可以使用以下方法仅保留最高1
集:
x ^= x >> 1;
计算向右移位直到达到 1 所需的次数,然后将该 1 向左移位相同的计数。
int ct=0;
while (x > 1) { ct++; x = x >> 1; }
x = x << ct;
一种方法是创建一个位掩码,然后右移该值。
也就是说,创建一个位掩码,使您的整数为“1000 ....”或“0 ...” - 取决于第一位是 0 还是 1。
然后取那个整数并右移它,直到它变成最低有效位,而不是最高有效位。例如,0b10000000 >> 8
是 1。
因此,首先,根据整数的大小,您必须进行移位,不管多少位都是相关的。
然后你必须创建位掩码。让我们取一个 1 字节的整数:
unsigned int i = 1 << 8
将创建一个整数 i,其最高有效位为 1。
或者你可以使用十六进制。你已经知道0xFF
==了11111111
。您实际上可以进一步分解它:0xF0
==11110000
因为0xF
==1111
是二进制的,好吧,我们将做相反的事情。1000
二进制是什么,十六进制?1000
在二进制中是数字8
,它也恰好等于0x8
因此,对于单个字节,最左边位的掩码是0x80
.
现在!将此应用于 32 位!
祝你好运!