位运算 tips
注意事项及技巧
A^B = AB’ + A’B
注意符号扩展!!!
注意有符号数右移时的符号位扩展
1
2
3
4
5
6
7
8int x = -1;
cout<<x<<endl; // 1111111...1111
cout<<(x>>31)<<endl; // 1111111...1111
// 发生符号位扩展,因为x为有符号数,且符号位为1。故右移时用1填充
cout<<((x>>31)&1)<<endl; // 00000000...0001
-1
-1
1两个int立即数异或出的结果立即数,也会进行符号扩展。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32int x = -2;
// int y = -5;
int y = 5;
cout<<x<<" "<<y<<endl;
int bitX = x>>31;
int bitY = y>>31;
cout<<bitX<<" "<<bitY<<endl;
cout<<(unsigned) bitX <<" "<<(unsigned )bitY<<endl;
cout<<"====="<<endl;
int check1 = (x>>31) ^ (y>>31); // 有符号数 异或出1,会进行符号扩展。在赋值给check1之前,就扩展为111111...1111。check1于是为-1:1111..111111
cout<<check1<<" " <<(unsigned )check1<<endl;
int check2 = bitX ^ bitY;
cout<<check2<<" "<<(unsigned )check2<<endl;
return 0;
y=-5:
-2 -5
-1 -1
4294967295 4294967295
=====
0 0
0 0
y=5:
-2 5
-1 0
4294967295 0
=====
-1 4294967295
-1 4294967295获得符号位的正确操作
1
2
3int x_sign = x>>31&1; // 获取x最高符号位,并将其放到0位
int y_sign = y>>31&1; // 获取y最高符号位,并将其放到0位
int sign_xor = x_sign ^ y_sign; // x和y符号位是否相同 相同为0,不同为1。
- 如何获取一个 m位二进制数(称为待分解数)的低x位
- 先定义一个 m位 unsigned 全f 掩码
- 然后利用unsigned特性(右移左侧补0)右移(m-x)位,然后得到x位全f掩码(高m-x位均为0)
- 将待分解数与x位全f掩码相&,
- 得到待分解数的低x位。
1
2
3
4unsigned long mask = 0xffffffffffffffff;
unsigned long xxxMask = mask >> (m-x); // 由于mask为unsigned 故左侧补0
unsigned long xxx = xxx & numberToDo;
printf("mask = %lx\txxxMask=%lx\txxx=%ld\n",mask,xxxMask,xxx); - 或者也可以通过先左移(m-x),再右移(m-x)。也是要利用unsigned无符号扩展。
