新知识-位运算(Leetcode 217_存在重复元素)
新知识-位运算
&、|、^、~、>>、<<
- 计算机对二进制位数进行的运算(+-*/),符号位共同参与运算。
-
按位与运算符(&)
(*)
两个1才为1,出0则0;-
负数先进行补码转换再进行
与运算
-
清零:将某数清零,将其所有位数与0相与,结果为0;
-
取指定位
- 比如10110010想取其后四位,只需要将其与00001111相与,也就是说,将需要获得的位数与1相与保留本身,将其他位与0想与,便可达到取位的作用.
- 10110010 & 00001111 = 00000010
-
判断奇偶
最末位为0为偶数,最末位为1为奇数
- 因此可以用(if ( a & 1 == 0)) 取代 (if (a % 2 == 0 )).
-
-
按位或运算符(|)
(+)
两个0才为0,出1则1;- 设1
- 某些位设1 0010010 | 01100000 = 11110010
- 设1
-
异或运算(^)
相同为0,不相同为1;
-
交换律、结合律、xx=0,x0=1、自反(a ^ b ^ b=a ^ 0=a)
-
翻转指定位 10111110 ^ 00001111 = 10110001
-
与0相异或值不变
-
交换2个数
-
void Swap(int &a, int &b){ if (a != b){ a ^= b; b ^= a; a ^= b; } }
-
-
-
取反运算符(~)
0变1,1变0
-
最低位变0
a & ~1 = 10110001 & 11111110 = 10110000
-
-
左移右移运算符
(<< >>)
-
所有位数左移,高位丢,低位补0
-
10110110 << 2 = 11011000
若
左移时舍弃的高位不包含1
,则每左移一位,相当于该数乘以2.
-
-
(>>) 所有位右移,无符号高位补0,有符号,各编译器分为算数右移(补符号位)和逻辑右移(补0)
-
-
不同长度的数据进行位运算:如果两个不同长度的数据进行位运算时,系统会将二者按右端对齐,然后进行位运算。
-
long与int相与 4个字节、2个字节,右边对齐,当
- 整数数据为正时,左边补16个0
- 为负,左边补16个1
- 无符号,左边补16个0
-