目录
引言
你熟悉进制吗,我们常用的计量单位之间的换算其实就是进制之间的换算。
生活中的例子: 12 颗鸡蛋是 1打,10 两 面粉是 1斤,24袋 牛奶是 1箱..等等
计算机编程中:我们常说的 1-10 就是 10进制;我们常说的原码补码中只有 0 和 1,这就是 2进制; 此外还有 8 进制 和 16 进制。
一、进制介绍
二进制
计算机中的运算都是通过二进制进行的,就像计算机中的加减法都可以通过加法器,用补码的方式实现,补码又根据数值的正负,由反码进行不同的演算而来,反码又通过原码和真值而来。掌握这些,就能让你更好的使用编程中的位运算来优化代码。
不过这些都是后话,我们今天先来讲讲什么是二进制。
在C语言中,要表示一个二进制,可以用 0b 作为前缀,然后跟上 0 和 1 组成的数字。
配以二进制的进位法则,即逢二进一。
所以我们可以举例:7 的二进制表达为 0b111;
二进制 | 1 | 10 | 11 | 100 | 101 | 110 | 111 |
十进制 | 1 | 2 | 3 | 4 | 5 | 6 | 7 |
八进制
八进制的表示方法是前缀单挂 1个 0,然后跟上 0-7 的数字。就像 0123 就表示一个八进制数。
写成代码就是: int a = 0123; printf("%d\n", a); //83 计算方式 3*8^0 + 2*8^1 + 1*8^2
int main(){
int x = 0123; //前缀为 0,表示是一个八进制数
printf("%d\n", x); //打印结果为转化的十进制数,即 83
return 0; //返回 0,表示运行无误
}
这里的 0123 转换为十进制 83 的计算公式为:3*8^0 + 2*8^1 + 1*8^2,是不是很简单啊?
十进制
十进制可能是我们用的最熟悉的,从1,2,3...10,再到循环的 i,我们用的都是十进制数。
十六进制
十六进制的表示方法是前缀 0X 或者 0x,跟上 0-9、a-f、A-F 的数字(不区分大小写),表示 0-15
例如: int a = 0X123; printf("%d\n", a); //291 计算方式 3*16^0 + 2*16^1 + 1*16^2
int main(){
int x = 0X123; //前缀为 0,表示是一个十六进制数
printf("%d\n", x); //打印结果为转化的十进制数,即 291
return 0; //返回 0,表示运行无误
}
二、进制转换
二进制和十进制
二进制转十进制通过阶乘运算。十进制转二进制通过除法的运算获得。
在二进制和十进制之间,他们最大的区别就是进位机制不同。
就拿同一个数 11 来说,
- 在十进制中,它是 10 + 1,其中 10 为进位结果, 1 为非进位结果,他们求和的结果就是 11。
- 然而用二进制表示的话,11 = 8 + 3,其中 8 为进位结果,3 为非进位结果,他们的求和结果就是11。
那么还是举 11 这个数的例子,
- 如何将它从十进制转换为 二进制供计算机运算呢?
这里我们用到了除法和求余运算。
除法 余数
2 | 11 1
———————
2 | 5 1
———————
2 | 2 0
————————
2 | 1 1
最后将获得的余数从下往上的方式顺次写下来,也就是 0b1011
十进制 | 11 | |||
二进制(0b) | 1 | 0 | 1 | 1 |
- 那么又如何通过二进制转换为十进制呢?
我们从低位往高位做乘法,最末尾的 1 表示有 1 个 2 ^ 0, 倒数第二位的 1 表示有 1 个 2 ^ 1,
倒数第三位的 0 表示 有 0 个 2 ^ 2,最高位的 1 表示有 1 个 2 ^ 3。
我们将他们整合相加,得到式子如下; 1 * 2^0 + 1 * 2^1 + 0 * 2^2 + 1 * 2^3 = 1 + 2 + 0 + 8 = 11.
二进制和八进制
如果我们通过进制之间的基本方式,需要先将二进制转换为十进制,再将十进制转换为八进制,效率较低。
然而,二进制和八进制做换算有更为简单的方式,这是因为 8 = 2 ^ 3;这也就意味着,我们只需要将每三位连续的二进制转换为一位八进制,就可以实现整个进制之间的换算。反之同理。
就拿 11 来讲,11 的二进制为 1011,位数不足,首位补 0,即 001011
001011 --> 分为 001 和 011
————————————————————————————
对应8进制为 1 和 3
二进制和十六进制
了解过二进制和八进制的转换,我们再上手二进制和十六进制就得心应手了。
我们首先知道 16 = 2 ^ 4;这样我们就可以将每四位二进制转换为一位 16 进制数,最后组合起来就实现了二进制转换十六进制。
还是拿 11 来讲,11 的二进制为 1011,正好四位。
十六进制中,0 ~ 9 分别由对应数字表示,从 10 开始 由 A - F(或 a - f)表示 10 ~ 15.
转换结果: 0b1011 --> 0XB
八进制和十进制
八进制同十进制的转换,跟二进制同十进制转换方式相同。
由十进制转换八进制用除法,每次除以 8,最后得到的余数就是我们的结果。
由八进制转换十进制用乘法,每次乘以对应的 8 的阶乘。
十六进制和十进制
十六进制也是一样的换算。由十进制转换十六进制用除法,每次除以 16,求得余数,需要注意的是如果余数大于 10 注意用字母代替表示。
由十六进制转换十进制用乘法。
结束语
进制是我们平常最容易忽略的,因为我们对于十进制的计算太过于熟练,而且当我们使用高级汇编语言时,我们也只需要接触十进制,不需要过多的了解进制之间的转换和应用。
那为什么计算机课程里进制转换是必修的内容呢? 而且有的老师会不止一遍的在多门课程中讲到它,归根结底是因为进制就是计算机的基础知识,有一个良好的基础,会让我们的纵向发展更加通畅,编程的思路也会因此打开。
所以我依旧强调基础学习的重要性,也希望这篇文章能够让你有所收获。可能我写的并不完善,会让初学者看不明白,如果那样请指教出来,我也会针对性的去修改完善。