5 进制
5.1 进制说明
-
对于整数,有如下表示方式:
- 2进制:0和1,满2进1,以0b或0B开头;
- 8进制:0-7,满8进1,以数字0o或者0O开头表示;
- 10进制:0-9,满10进1;
- 16进制:0-9及A(10)-F(15),满16进1,以0x或0X开头表示。此处的A-F不区分大小写;
-
图示:
十进制 十六进制 八进制 二进制 0 0 0 0 1 1 1 1 2 2 2 10 3 3 3 11 4 4 4 100 5 5 5 101 6 6 6 110 7 7 7 111 8 8 10 1000 9 9 11 1001 10 A 12 1010 11 B 13 1011 12 C 14 1100 13 D 15 1101 14 E 16 1110 15 F 17 1111 16 10 20 10000 17 11 21 100001
5.2 其它进制转十进制
-
二进制转十进制:从最低位(右边)开始,将每个位上的数提取出来,乘以2的(位数-1)次方,然后求和;
例: 0 b 1011 = 1 × 2 3 + 0 × 2 2 + 1 × 2 1 + 1 × 2 0 = 8 + 0 + 2 + 1 = 11 例:0b1011 = 1 \times 2^3 + 0 \times 2^2 + 1 \times 2^1 + 1 \times 2^0 = 8 + 0 + 2 + 1 = 11 例:0b1011=1×23+0×22+1×21+1×20=8+0+2+1=11 -
八进制转十进制:从最低位(右边)开始,将每个位上的数提取出来,乘以8的(位数-1)次方,然后求和;
例: 0 o 234 = 2 × 8 2 + 3 × 8 1 + 4 × 8 0 = 156 例:0o234 = 2 \times 8^2 + 3 \times 8^1 + 4 \times 8^0 = 156 例:0o234=2×82+3×81+4×80=156 -
十六进制转十进制:从最低位(右边)开始,将每个位上的数提取出来,乘以16的(位数-1)次方,然后求和;
例: 0 x 23 A = 2 × 1 6 2 + 3 × 1 6 1 + 10 × 8 0 = 570 例:0x23A = 2 \times 16^2 + 3 \times 16^1 + 10 \times 8^0 = 570 例:0x23A=2×162+3×161+10×80=570 -
练习:
0 b 110001100 = 369 0b110001100 = 369 0b110001100=3690 o 2456 = 2629 0o2456 = 2629 0o2456=2629
0 x A 45 = 1326 0xA45 = 1326 0xA45=1326
5.3 十进制转其他进制
-
十进制转二进制:
-
规则:将该数不断除以2,直到商为0为止或不够除,然后将每步得到的余数倒过来(如果商不为0且不够除的时候,要把商算上),就是对应的二进制(倒数取余法);
-
例:34的二进制是0b100010;
-
验证:
print(bin(34))
-
-
十进制转八进制:
-
规则:将该数不断除以8,直到商为0为止或不够除,然后将每步得到的余数倒过来(如果商不为0且不够除的时候,要把商算上),就是对应的八进制(倒数取余法);
-
例:121的八进制是0o203;
-
验证:
print(oct(131))
-
-
十进制转十六进制:
-
规则:将该数不断除以16,直到商为0为止或不够除,然后将每步得到的余数倒过来(如果商不为0且不够除的时候,要把商算上),就是对应的十六进制(倒数取余法);
-
例:237的十六进制是0xED
-
验证:
print(hex(237))
-
-
练习:
print(bin(123)) # 0b1111011 print(oct(678)) # 0o1246 print(hex(8912)) # 0x22d0
5.4 二进制转八进制和十六进制
- 二进制转八进制:
- 规则:从低位开始,将二进制数每三位一组(高位不够则高位补零),转成对应的八进制数即可;
- 例:0b11010101 -> 011 010 101 -> 0o325
- 二进制转十六进制:
- 规则:从低位开始,将二进制数每四位一组(高位不够则高位补零),转成对应的十六进制数即可;
- 例:0b11010101 -> 1101 0101 -> 0xD5
- 练习:
- 0b11100101 -> 0o345
- 0b1110010110 -> 0x396
5.5 八进制和十六进制转二进制
-
八进制转二进制:
- 规则:将八进制数每1位,转成对应的一个3位的二进制数即可;
- 例:0o237 -> 0b010011111
-
十六进制转二进制:
- 规则:将十六进制数每1位,转成对应的4位的一个二进制数即可;
- 例:0x23B -> 0b001000111011
-
练习:
- 0o1230 -> 0b001010011000
- 0xAB29 -> 0b1010101100101001
5.6 原码反码补码
- 二进制的最高位是符号位:0表示正数,1表示负数;
- 假设用一个字节来表示整型:
- 3对应的二进制就是0000 0011;
- -3对应的二进制就是1000 0011;
- 假设用一个字节来表示整型:
- 正数的原码、反码和补码都一样;
- 3的原码:0000 0011;
- 3的反码:0000 0011;
- 3的补码:0000 0011;
- 负数的反码 = 它的原码符号位不变,其它位按位取反(即0变1,1变0);
- -3的原码:1000 0011;
- -3的反码:1111 1100;
- 负数的补码 = 它的反码+1,即负数的反码 = 负数的补码 - 1;
- -3的原码:1000 0011;
- -3的反码:1111 1100;
- -3的补码:1111 1101
- 0的反码、补码都是0;
- 计算机在运算的时候,都是以补码来进行运算的;
- 1 + 3 =>
- 1 => 补码:0000 0001
- 3 => 补码:0000 0011
- 1 + 3 => 0000 0100 => 补码
- 1 - 3 =>
- 1 => 补码:0000 0001
- -3 => 原码:1000 0011 => 反码:1111 1100 => 补码:1111 1101
- 1 - 3 => 1 + (-3)
- 1的补码:0000 0001
- -3的补码:1111 1101
- 结果补码:1111 1110
- 1 + 3 =>
- 最后计算机是将补码转成原码输出;
- 接上例1 + 3,补码0000 0100是正数,又因为正数原反补三码相同,所以原码也是0000 0100,再二进制转十进制,得到结果4;
- 接上例1 - 3,补码1111 1110是负数,得反码1111 1101,得源码1000 0010,得到结果-2。
5.7 位运算符
-
按位取反
~
- 规则:对数据的每个二进制位取反,即把1变成0,把0变成1;
~-2
= 1- 运算:-2的原码:1000 0010 => -2的反码:1111 1101 => -2的补码:1111 1110,对-2的补码
~
运算得到:0000 0001(补码); - 0000 0001(补码) => 0000 0001(原码)=> 1
- 运算:-2的原码:1000 0010 => -2的反码:1111 1101 => -2的补码:1111 1110,对-2的补码
~2
= -3- 运算:2的原码:0000 0010 => 2的补码:0000 0010,对2的补码
~
运算得到:1111 1101(补码); - 1111 1101(补码)=> 1111 1100(反码)=> 1000 0011(原码)=> -3
- 运算:2的原码:0000 0010 => 2的补码:0000 0010,对2的补码
-
按位与
&
(相同才为1)- 规则:参与运算的两个值,如果两个相应位都为1,则该位的结果为1,否则为0;
2 & 3
= 2- 2的补码:0000 0010
- 3的补码:0000 0011
- 按位与: 0000 0010(补码) => 0000 0010(原码)=>2
-
按位异或
^
(不同才为1)- 规则:当两个对应的二进制位相异时,结果为1;
2 ^ -3
= -1- 2的补码: 0000 0010
- -3的补码:1111 1101
- 按位异或:1111 1111(补码) => 1111 1110(反码) => 1000 0001(原码) => -1
-
按位或
|
(有一个1就为1)- 规则:只要对应的两个二进位有一个为1时,结果位就为1;
2 | 3
= 3- 2的补码:0000 0010
- 3的补码:0000 0011
- 安慰或: 0000 0011(补码)=> 0000 0011(原码)=> 3
-
左移运算符
<<
(乘2)- 规则:运算数的各二进位全部左移若干位,符号位不变,高位丢弃,低位补0;
5 << 1
,即将5的补码左移1位,结果是10- 5的补码:0000 0101
- 将 0000 0101(补码)左移一位;
- 0xxx xxxx (补码)先符号位不变;
- 0000 101x(补码)高位丢弃(加粗的数字),将黄色部分左移,右边低位补0;
- 0000 1010(补码)=> 0000 1010(原码)=>10
-5 << 1
,即将-5的补码左移1位,结果是-10- -5的原码:1000 0101 => 1111 1010(反码)=> 1111 1011(补码)
- 将 1111 1011(补码)左移一位;
- 1xxx xxxx (补码)先符号位不变;
- 1111 011x(补码)高位丢弃(加粗的数字),将黄色部分左移,右边低位补0;
- 1111 0110(补码)=> 1111 0101(反码)=> 1000 1010(原码)=> -10
-
右移运算符
>>
(除2,向上取整)- 规则:运算数的各二进位全部右移若干位,符号位不变,低位溢出,并用符号位补溢出的高位;
5 >> 1
,即将5的补码右移1位,结果是2- 5的补码:0000 0101
- 将 0000 0101(补码)右移一位;
- 0xxx xxxx (补码)先符号位不变;
- 0x00 0010(补码)低位溢出(加粗的数字),将黄色部分右移,左边高位用符号补溢出的高位;
- 0000 0010(补码)=> 0000 0010(原码)=> 2
-5 >> 1
,即将5的补码右移1位,结果是-2- -5的原码:1000 0101 => 1111 1010(反码)=> 1111 1011(补码)
- 将 1111 1011(补码)右移一位;
- 1xxx xxxx (补码)先符号位不变;
- 1x11 1101(补码)低位溢出(加粗的数字),将黄色部分右移,左边高位用符号补溢出的高位;
- 1111 1101(补码)=> 1111 1100(反码)=> 1000 0011(原码)=> -2