这就是你需要的:
int logical_right_shift(int x, int n)
{
int size = sizeof(int) * 8;
return (x >> n) & ~(((0x1 << size) >> n) << 1);
}
解释
x >> n
表示将 x
向右移动 n
位。然而,如果 x
是负数,则符号位(最左边的位)将会被复制到右边,例如:
假设这里的每个 int 都是 32 位,让
x = -2147483648 (10000000 00000000 00000000 00000000)
,则
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)
&
操作就能解决问题。
而这个函数的总成本是 6
次操作。
return (n == 0 ? x : (x >> n) & ~(((x >> (size << 3) - 1) << (size << 3) -1)) >> (n-1));
- Mateen Ulhaq