二进制与位运算

带你从数据小白成长为数据分析师

返回

二进制

例子:15

15
十进制1*10^1 + 5*10^0 = 15
1111
二进制1*2^3 + 1*2^2 + 1*2^1 + 1*2^0 = 8+4+2+1 = 15

原码、反码、补码

这三个码的产生,都和表示减法(负数)有关,他们的正数表示完全一样

十进制 二进制 负数十进制 原码 反码 补码
0 0000 -0 1000 1111 0000
1 0001 -1 1001 1110 1111
2 0010 -2 1010 1101 1110
3 0011 -3 1011 1100 1101
4 0100 -4 1100 1011 1100
5 0101 -5 1101 1010 1011
6 0110 -6 1110 1001 1010
7 0111 -7 1111 1000 1001

原码

原码用最高位存放符号,正数为0, 负数为1。后面位数表示数字 即:正数的二进制最高位为0,负数的二进制最高位为1

反码

正数的反码与原码一样

负数的反码为负数原码的数字位取反,也就是将正数的反码全部取反

补码

算法一: 正数的补码和正数的原码完全一样,负数的补码等于负数的反码+1

算法二: 模:在四位二进制码的空间里,最大能表示15,所以16就是模,即10000 正数补码不变,求负数补码用模减去其十进制即可。 例子:计算-2的补码,其实就转化成: 10000 -0010 =1110

算法三: 负数x的补码是x+1的反码 例子:-2的补码1110,是-1的反码

位运算符

计算机底层在存储数据的时候,都是用补码存储,位运算符就是基于补码进行的计算

位运算符 名称 算法 例子
& 按位于 两个二进制数相应位都为1,则该为的结果为1,否则为0 (101)^(110)=100
| 按位或 两个二进制相应位置有一个为1时,结果位就为1 (101)^(110)=111
^ 按位异或 两个二进制数相应位不同时,结果位1 (101)^(110)=011
~ 按位取反 对二进制进行取反,即1取反为0,0取反为1 ~(101)=010
« 按位左移 将二进制数左移n位,相当于乘以2的n次方 (101)«1=1010
» 按位右移 将二进制数右移n位,相当于除以2的n次方,不能整除则向下取整 (100)»1=010
# 例子
a = 0010  #2
b = 0011  #3

a&b = 0010 & 0011= 0010  #2  "都1 则1,否则0"
a|b = 0010 | 0011= 0011  #3  "有1 则1"
a^b = 0010 ^ 0011= 0001  #1  "不同则1,否则0"
~a = ~0010 = 1101        #-3 "取反,-n-1"

a<<1 = 0100 #左移一位,相当于乘2,得到4
a>>1 = 0001 #右移一位,相当于除以2,得到1
a>>2 = 0000 #右移两位,相当于除以4,不能整除时向下取整,得到0

# 输出补码
def complement_code(x):
    if x <0 :
        # return bin(x & ((1<<(len(bin(x))-2))-1)).replace("0b","")
        return bin((1<<(len(bin(x))-2))+x).replace("0b","")
    else:
        return "0"+bin(x).replace("0b","")