0%

左移与右移

左移与右移:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
">>"右移
操作规则:最低位丢弃。正数前面补零,负数前面补1
"<<"左移
操作规则:最高位丢弃。无论正负数,后面补零。
建议:左右移时参数最好限定为无符号数或正整数。有符号数需要注意的地方太多了。

有符号数:
根据内存分布,按上述规则移动。
左移:由于有符号数最高位为符号位,左移时可能会发生符号位变化所以最好自己根据内存分布计算。
右移:如果数为正,不溢出的情况下,每移一位相当于除以2并向下取整,等价于除以2。如果数为负,每移一位相当于除以2并向上取整。如-1,-1/2 = -0.5向上取整 = -1。-3,-3/2 = -1.5向上取整 = -2

无符号数:
左移:不溢出的情况下,左移一位相当于乘2
右移:不溢出的情况下,右移一位相当于除2并向下取整,等价于除以2

n = 1010 1000
n - 1 = 1010 0111
n & (n - 1) = 1010 0000 //相当于将n的最右边的1消为0n为正数或负数都可以。
而右移需要参数为正数。
在数二进制1的个数方面,n & (n - 1)是最佳解决办法。

代码:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
char a = -3;
printf("a = %d\n", a);

int cnt = hammingWeight(a); //会被强转为int。
printf("cnt = %d\n", cnt);

char b = a >> 1;
printf("b = %d,a / 2 = %d\n", b, a / 2);

unsigned char c = 3;
printf("c = %d\n", c);

unsigned char d = c >> 1;
printf("d = %d\n", d);


int hammingWeight(int n) {
int cnt = 0;
while (n != 0) {
cnt += 1;
n &= n - 1;
}
return cnt;
}

打印:

1
2
3
4
5
a = -3
cnt = 31
b = -2,a / 2 = -1
c = 3
d = 1
觉得文章有帮助可以打赏一下哦!