【问题描述】[简单]
【解答思路】
1. 位运算
时间复杂度:O(1) 空间复杂度:O(1)
public int add(int a, int b) {while(b != 0) { // 当进位为 0 时跳出int c = (a & b) << 1; // c = 进位a ^= b; // a = 非进位和b = c; // b = 进位}return a;}
【总结】
1. 位运算
异或运算(^)
运算规则:0^0=0; 0^1=1; 1^0=1; 1^1=0;
即:参加运算的两个对象,如果两个相应位为“异”(值不同),则该位结果为1,否则为0。
5 ^ 1 = 0101 ^ 0001 = 0100 = 4
5 ^ 3 = 0101 ^ 0011 = 0110 = 6
用法
翻转指定位 对应位异或1
X=10101110,使X低4位翻转,用X ^0000 1111 = 1010 0001即可得到。
2.两个数是否相等 ==0
5 ^ 5 = 0101 ^ 0101 = 0000 = 0
与运算(&)
运算规则:0&0=0; 0&1=0; 1&0=0; 1&1=1;
即:两位同时为“1”,结果才为“1”,否则为0
5 & 1 = 0101 & 0001 = 0001 = 1
5 & 2 = 0101 & 0010 = 0000 = 0
用法
取指定位 对应位与1
设X=10101110,
取X的低4位,用 X & 0000 1111 = 00001110 即可得到;
或运算(|)
运算规则:0|0=0; 0|1=1; 1|0=1; 1|1=1;
即 :参加运算的两个对象只要有一个为1,其值为1
用法:
指定位置置1 对应位或1
将X=10100000的低4位置1 ,用X | 0000 1111 = 1010 1111即可得到
取反运算(~)
运算规则:~1=0; ~0=1;
即:对一个二进制数按位取反,即将0变1,1变0
带符号左移运算(<<)
若左移时舍弃的高位不包含1,则每左移一位,相当于该数乘以2(右边补0)
3 << 1 = 0011 <<1 = 0110 = 6
带符号右移运算(>>)
正数操作数每右移一位,相当于该数除以2
(左补0 or 补1得看被移数是正还是负)
5 >> 1 = 0101 >> 1 = 0010 = 2
5 >> 2 = 0101 >> 2 = 0001 = 1
-14 >> 2 = 11110010 >> 2 = 11111100 = -4
无符号右移运算(>>>)
5 >>> 1 = 0101 >>> 1 = 0010 = 2
-14 >>>2 =11111111 11111111 1111111111110010 >>>2 = 00111111 11111111 1111111111111100 = 1073741820
移位总结
- 正数的左移与右移,负数的无符号右移,就是相应的补码移位所得,在高位补0即可。
- 负数的右移,就是补码高位补1,然后按位取反加1即可。
2. 位运算 判相等异或^ 取位与&1 置位或|1
3.扩展知识
Python 负数的存储
print(hex(1)) # = 0x1 补码
print(hex(-1)) # = -0x1 负号 + 原码 ( Python 特色,Java 会直接输出补码)print(hex(1 & 0xffffffff)) # = 0x1 正数补码
print(hex(-1 & 0xffffffff)) # = 0xffffffff 负数补码print(-1 & 0xffffffff) # = 4294967295 ( Python 将其认为正数)
作者:jyd
转载链接:https://leetcode-cn.com/problems/bu-yong-jia-jian-cheng-chu-zuo-jia-fa-lcof/solution/mian-shi-ti-65-bu-yong-jia-jian-cheng-chu-zuo-ji-7/