Dan*_*Dan 16 c bit-manipulation
我正在使用仅按位运算符在C中创建逻辑右移位函数.这就是我所拥有的:
int logical_right_shift(int x, int n)
{
int size = sizeof(int); // size of int
// arithmetic shifts to create logical shift, return 1 for true
return (x >> n) & ~(((x >> (size << 3) - 1) << (size << 3) -1)) >> (n-1);
}
Run Code Online (Sandbox Code Playgroud)
这实际上适用于所有情况,除非n = 0.我一直试图找到一种方法来解决它,所以它也适用于n = 0,但我卡住了.
Ign*_*ams 29
int lsr(int x, int n)
{
return (int)((unsigned int)x >> n);
}
Run Code Online (Sandbox Code Playgroud)
min*_*gyc 13
这就是你需要的:
int logical_right_shift(int x, int n)
{
int size = sizeof(int) * 8; // usually sizeof(int) is 4 bytes (32 bits)
return (x >> n) & ~(((0x1 << size) >> n) << 1);
}
Run Code Online (Sandbox Code Playgroud)
说明
x >> n转移n bits的权利.但是,如果x是负数,则符号位(最左边的位)将被复制到其右侧,例如:
假设每个int 在这里是32位,let
x???? =?-2147483648?(10000000 00000000 00000000 00000000),then
x?>>?1?=?-1073741824?(11000000 00000000 00000000 00000000)
x?>>?2?=?-536870912? (11100000 00000000 00000000 00000000)
等等.
因此,当n为负时,我们需要删除那些符号额外符号位.
假设n = 5在这里:
0x1 << size移到1最左边的位置:
(10000000 00000000 00000000 00000000)
((0x1 << size) >> n) << 1将1复制到其n-1邻居:
(11111000 00000000 00000000 00000000)
~((0x1 << size) >> n) << 1! 反转所有位:
(00000111 11111111 11111111 11111111)
所以我们最终获得了一个掩码来提取真正需要的东西x >> n:
(x >> n) & ~(((0x1 << size) >> n) << 1)
Run Code Online (Sandbox Code Playgroud)
该&操作是卓有成效的.
而这个功能的总成本是6运营.
只需将您的存储在int中unsigned int,然后对其执行>>。
(如果使用 unsigned int,则不会扩展或保留符号)