转发请标注原文链接: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]原
参考资料:
- 极客时间-程序员的数学基础课
- 结城浩-程序员的数学
下面是极客时间的该课程快捷入口: