源码、反码和补码
原码:最高位符号位,其余对齐本身值即可
反码(反码,反的是原码):
* 正数:反码和原码一致
* 负数:符号位为1,其余位对原码取反
补码(补码,补的就是反码):
* 正数:补码和原码一致
* 负数:符号位为1,其余位反码+1
1 2 3 4 5 6 7 8 9
| 7 原码:0 0 0 0 0 1 1 1 反码:0 0 0 0 0 1 1 1 补码:0 0 0 0 0 1 1 1
-7 原码:1 0 0 0 0 1 1 1 反码:1 1 1 1 1 0 0 0 补码:1 1 1 1 1 0 0 1
|
位运算
与、或、异或、非
与运算(and &)
1 2 3 4 5
| 1 0 1 1 1 1 0 0 0 1 1 1 0 0 0 0 and ------------------------- 0 0 1 1 0 0 0 0
|
或运算(or |)
1 2 3 4 5
| 1 0 1 1 1 1 0 0 0 1 1 1 0 0 0 0 or ------------------------- 1 1 1 1 1 1 0 0
|
异或运算(xor ^)
1 2 3 4 5
| 1 0 1 1 1 1 0 0 0 1 1 1 0 0 0 0 or ------------------------- 1 1 0 0 1 1 0 0
|
非运算(单目运算符 not ~)
1 2 3 4
| 1 0 1 1 1 1 0 0 not ------------------------- 0 1 0 0 0 0 1 1
|
位运算(移动位)
左移(<<)
1 2
| 0000 0001 所有二进制位全部向左移动若干位,高位丢弃,低位补零 0000 0010
|
右移(>>)
1 2
| 0000 0010 所有二进制位全部向右移动若干位,高位补零(或一,由符号位决定),低位丢弃 0000 0001
|
位运算实现加减乘除
加法
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
| 4 + 5 0000 0100 + 0000 0101
第一步,异或,如果不考虑进位,异或就可以直接出结果 0000 0100 0000 0101 -------------- 0000 0001
第二步,与运算(判断进位,如果与运算位0,则没有进位) 0000 0100 0000 0101 -------------- 0000 0100
第三步,将与运算的结果左移一位,0000 1000
第四步,异或 将第一步和第三步的结果进行异或运算 0000 0001 0000 1000 ------------------ 0000 1001
第五步,验算,将第一步和第三步的结果进行与运算,如果为0, 则第四步则为最终结果,如果不为0,则有进位,则与第四步结果异或 0000 0001 0000 1000 ------------------ 0000 0000
|
伪代码
1 2 3 4 5 6 7 8 9
| def add(a, b): c = a ^ b d = a & b if d == 0: # 没有进位,直接返回结果 return c else: d = d << 1 add(c, d)
|
减法
4 - 5 = 4 + (-5)
0000 0100 + 1111 1011 (计算机中负数存储的是补码)