前言:在学习C语言的过程中,我们经常能听到 2进制、8进制、10进制、16进制 这样的讲法,那是什么意思呢?
其实2进制、8进制、10进制、16进制是数值的不同表示形式罢了。
比如:数值15的各种进制的表示形式:
15的2进制:1111
15的8进制:17
15的10进制:15
15的16进制:F
//16进制的数值之前写:0x
//8进制的数值之前写:0
接下来,我们来细细描述进制的转换是如何进行。
目录
一、基础知识
1. C语言中的进制
C语言中的数值可以用 2进制、8进制、10进制、16进制 来表示。
为了避免8进制、16进制与10进制混淆,C语言规定:
在八进制数字前要加0(注意这里是数字零,不是大写字母O),在十六进制数字前要加0X或0x(注意这里同样是数字零,不是大写字母O),而在十进制数字前不需要加任何东西。
int i = 10; //表示十进制数字
int j = 010; //表示八进制数字
int k = 0x10; // 表示十六进制数字
int l = 0X10; // 表示十六进制数字
2. 汇编中的进制
汇编语言中,在数字后加字母B
表示二进制数字,在数字后加字母O
表示八进制数字,在数字后加字母D
表示十进制数字,在数字后加字母H
表示十六进制数字。
例如:
1011B表示二进制数字1011
1357O表示八进制数字1357
2049D表示十进制数字2049
3FB9H表示十六进制数字3FB9
3. 常见进制的基数
二进制:0 1
八进制:0 1 2 3 4 5 6 7
十进制:0 1 2 3 4 5 6 7 8 9
十六进制:0 1 2 3 4 5 6 7 8 9 a b c d e f
或者是这样:0 1 2 3 4 5 6 7 8 9 A B C D E F
4. 不同进制的输出方式
可以使用不同的占位符对数值进行格式化输出:
#include <stdio.h>
int main()
{
int i = 31;
printf("i = %d\n", i); // %d表示以十进制输出整型数据
printf("i = %o\n", i); // %o表示以八进制输出整型数据,注意这里是小写字母o
printf("i = %x\n", i); // %x表示以十六进制输出整型数据,如果数字中包含字母时,字母为小写
printf("i = %X\n", i); // %X表示以十六进制输出整型数据,如果数字中包含字母时,字母为大写
printf("i = %#x\n", i); // %o表示以十六进制输出整型数据,输出结果中带有0x
printf("i = %#X\n", i); // %o表示以十六进制输出整型数据,输出结果中带有0X
return 0;
}
运行结果:
i = 31
i = 37
i = 1f
i = 1F
i = 0x1f
i = 0X1F
二、十进制与任意进制的相互转换
1. 权重的理解
我们生活中最常见的是10进制的数值。
我们把10进制作为切入口,来看看权重该如何理解。
其实10进制的123表示的值是⼀百⼆⼗三,为什么是这个值呢?其实10进制的每⼀位是有权重的,10
进制的数字从右向左是个位、⼗位、百位…,分别每⼀位的权重是 100 、101 、102……
如:
10进制的位 | 1 | 2 | 3 |
---|---|---|---|
权重 | 102 | 101 | 100 |
权重值 | 100 | 20 | 3 |
求值:1 * 10^2^ + 2 * 10^1^ + 3 * 10^0^
1 * 100 + 2 * 10 + 3 * 1 = 123
以此类推,2进制、8进制、16进制亦是如此。
如:
7的二进制0111
转为10进制:
2进制的位 | 0 | 1 | 1 | 1 |
---|---|---|---|---|
权重 | 23 | 22 | 21 | 20 |
权重值 | 0 | 4 | 2 | 1 |
求值:0 * 2^3^ + 1 * 2^2^ + 1 * 2^1^ + 1 * 2^0^
0 * 8 + 1 * 4 + 1 * 2 + 1 * 1 = 7
如:
15的八进制017
转为10进制:
8进制的位 | 1 | 7 |
---|---|---|
权重 | 81 | 80 |
权重值 | 8 | 7 |
求值:1 * 8^1^ + 7 * 8^0^
1 * 8 + 7 * 0 = 15
如:
15的十六进制0xf
转为10进制:
16进制的位 | f |
---|---|
权重 | 160 |
权重值 | 15 |
求值:f * 16^0^
f * 1 = 15
15 * 1 = 15
2. 除基取余法(也称除n取余法)
除基取余法运用于10进制转为各种进制:
如:
10进制的23
转为二进制:
步骤 | 除法运算 | 商 | 余数 |
---|---|---|---|
1 | 23➗2 | 11 | 1 |
2 | 11➗2 | 5 | 1 |
3 | 5➗2 | 2 | 1 |
4 | 2➗2 | 1 | 0 |
5 | 1➗2 | 0 | 1 |
从表格最后一行的余数开始,由下往上依次排列,即得到23
(十进制)对应的二进制数10111
(二进制)。
如:
10进制的23
转为八进制:
步骤 | 除法运算 | 商 | 余数 |
---|---|---|---|
1 | 23➗8 | 2 | 7 |
2 | 2➗8 | 0 | 2 |
从表格最后一行的余数开始,由下往上依次排列,即得到23
(十进制)对应的八进制数27
(八进制)。
如:
10进制的23
转为十六进制:
步骤 | 除法运算 | 商 | 余数 |
---|---|---|---|
1 | 23➗16 | 1 | 7 |
2 | 1➗16 | 0 | 1 |
从表格最后一行的余数开始,由下往上依次排列,即得到23
(十进制)对应的八进制数17
(十六进制)。
三、二进制与八进制的相互转换
- 思考:1个八进制位需要多少个二进制位来表示?
八进制的最高基数是7
,用二进制表示是111
,说明三个二进制足以表示一个八进制。
所以二进制转为八进制,我们只需要二进制三个三个为一组即可。
方法:从右向左,三位一段,不够补零,按十进制,分段转换
二进制转八进制:
1111010101110110111 二进制
001 111 010 101 110 110 111 三个为一组
———————————————————————————
1 7 2 5 6 6 7 八进制
八进制转二进制:同理八进制的一位转二进制的三位。
八进制转二进制:
1725667 -->八进制
1 7 2 5 6 6 7 八进制
001 111 010 101 110 110 111 二进制
四、二进制与十六进制的相互转换
- 思考:1个十六进制位需要多少个二进制位来表示?
八进制的最高基数是f
,用二进制表示是1111
,说明四个二进制足以表示一个十六进制。
所以二进制转为十六进制,我们只需要二进制四个四个为一组即可。
方法:从右向左,四位一段,不够补零,按十进制,分段转换
二进制转十六进制:
1111010101110110111 二进制
0111 1010 1011 1011 0111 四个为一组
———————————————————————————
7 a b b 7 十六进制
十六进制转二进制:同理十六进制的一位转二进制的四位。
十六进制转二进制:
7abb7 ----> 十六进制
7 a b b 7 十六进制
0111 1010 1011 1011 0111 二进制
五、总结
学习完进制转化有助于学习计算机更底层的知识,它将为补码、汇编、调试等的学习打下坚实的基础。
完结撒花!