DeepOps的程序员数学小笔记-二进制

转发请标注原文链接:http://www.mimiq.com.cn/?p=418

1 二进制

电路只有开、关两种状态。使用 0 、1 表示。十进制中 10 为基数,二进制中 2 为基数

1.1 python 十进制 转换为 二进制、八进制、十六进制

# 十进制 --> 二进制
n2 = 17
r2 = bin(n2)   

# 十进制 --> 八进制
n8 = 17
r8 = oct(n8)   

# 十进制 --> 十六进制
n16 = 17
r16 = hex(n16) 

print(n2,' --> ',r2)  
print(n8,' --> ',r8)
print(n16,' --> ',r16) 
#result:
17  -->  0b10001
17  -->  0o21
17  -->  0x11

1.2 python 二进制、八进制、十六进制 转换为 十进制

# 二进制 --> 十进制
s2 = '0b10001'
r2 = int(s2,base=2) 

# 八进制 --> 十进制
s8 = '0o21'
r8 = int(s8,base=8) 

# 十六进制 --> 十进制
s16 = '0x11'
r16 = int(s16,base=16) 

print(s2,' --> ',r2)  
print(s8,' --> ',r8)
print(s16,' --> ',r16) 
#result:
0b10001  -->  17
0o21  -->  17
0x11  -->  17

1.3 其他一些用法

s = '11'
r1 = int(s,base=16) # 16进制 可以不加0x
r2 = int(s,base=9)  # 9进制 转换为 10进制

print(s,' --> ',r1) 
print(s,' --> ',r2)
#result:
11  -->  17
11  -->  10

2 二进制的位操作

2.1 向左移位

# 正数
n=26
print(n)
print(bin(n))
n2=n<<2       # 左移2位
print(n2)
print(bin(n2))

n3=n<<60
print(n3)
print(bin(n3))
# 负数
n=-26
print(n)
print(bin(n))
n2=n<<2
print(n2)
print(bin(n2))

n3=n<<60
print(n3)
print(bin(n3))
#result:
26
0b11010
104
0b1101000
29975959119778021376
0b11010000000000000000000000000000000000000000000000000000000000000
-26
-0b11010
-104
-0b1101000
-29975959119778021376
-0b11010000000000000000000000000000000000000000000000000000000000000

2.2 向右移位

右移操作区分:算术右移 逻辑右移逻辑右移使用>>>(python中无逻辑右移操作符,没有java重编码测试),右移后左边补0;算术右移使用>>,右移后,符号位右侧补1。负数采用补码方式记录。

# 正数
n=53
print(n)
print(bin(n))
n2=n>>1
print(n2)
print(bin(n2))
n3=n>>7
print(n3)
print(bin(n3))
# 负数
n=-53
print(n)
print(bin(n))
n2=n>>1
print(n2)
print(bin(n2))
n3=n>>7
print(n3)
print(bin(n3))
#result
53
0b110101
26
0b11010
0
0b0

-53
-0b110101
-27
-0b11011
-1
-0b1

2.3 位的“或”、“与”、“异或”、非

a = 60
b = 13
print('a:',bin(a))
print('b:',bin(b))


print('a&b:',bin(a&b))
print('a|b:',bin(a|b))
print('a^b:',bin(a^b))
print('~a:',bin(~a))

a1=-60
print('a1:',bin(a1))
print('~a1:',bin(~a1))
result:
a: 0b111100
b: 0b1101

a&b: 0b1100
a|b: 0b111101
a^b: 0b110001
~a: -0b111101

a1: -0b111100
~a1: 0b111011

3 原码、反码 和 补码

参考:https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html

原码
原码就是符号位加上真值的绝对值, 即用第一位表示符号, 其余位表示值. 比如如果是8位二进制:
[+1]原 = 0000 0001
[-1]原 = 1000 0001
第一位是符号位. 因为第一位是符号位, 所以8位二进制数的取值范围就是:[1111 1111 , 0111 1111],即[-127 , 127]

反码
反码的表示方法是:
正数的反码是其本身
负数的反码是在其原码的基础上, 符号位不变,其余各个位取反.
[+1] = [00000001]原 = [00000001]反
[-1] = [10000001]原 = [11111110]反

补码
补码的表示方法是:
正数的补码就是其本身
负数的补码是在其原码的基础上, 符号位不变, 其余各位取反, 最后+1. (即在反码的基础上+1)
[+1] = [00000001]原 = [00000001]反 = [00000001]补
[-1] = [10000001]原 = [11111110]反 = [11111111]补

反码解决 1-1=0 的问题:

1 – 1 = 1 + (-1) = [0000 0001] + [1000 0001]= [0000 0001] + [1111 1110] = [1111 1111] = [1000 0000] = -0

码解决了反码相加 等于 -0 的问题:

1-1 = 1 + (-1) = [0000 0001] + [1000 0001] = [0000 0001] + [1111 1111] = [0000 0000]=[0000 0000]


参考资料:

  • 极客时间-程序员的数学基础课
  • 结城浩-程序员的数学

下面是极客时间的该课程快捷入口: