二进制/八进制/十进制/十六进制 怎么学会?是怎么算的方式?

能耐心点教我,谢谢
关注者
795
被浏览
639,037

36 个回答

生活中,人脑对很多事物都形成了条件反射,比如数字,习惯了十进制的我们可以很方便的对数字25、27进行大小比较和数值运算,却很难对二进制数字11001、11011有直观的感受。

其实想要弄清楚这些进制很简单,十进制各位都很熟悉,那先从十进制入手。

十进制计数规则是:

  • 基数为10。
  • 有10个数字,0、1、2、3、4、5、6、7、8、9。
  • 逢10进1,借1当10。

那么,二进制计数规则就是:

  • 基数为2。
  • 有2个数字,即0和1。
  • 逢2进1,借1当2。

十进制可以有多位组成,从右向左依次为个位、十位、百位、千位、万位...

于此类似,那么二进制也可以由多位数组成,从右向左分别为1位、2位、4位、8位、16位...

为什么称二进制的位数为1位、2位、4位...

其实这是从十进制的角度看二进制各位数得出的名称。

看上表,当二进制产生进位时,代表的十进制数为2、4、8、16、32、64、128...

二进制虽然只有0和1两个数字,但是由于数字所处的位置不同,表示的数据也不同,例如:


二进制数 “1011”


这个二进制数共有4位,由3个1和1个0组成,比如数字1所处位置不同,所代表的大小也不同,其所处位置称作权。从右向左顺序各个位表示十进制的含义:

第一个1表示:1的个数

第二个1表示:2的个数

第三个0表示:4的个数

第四个1表示:8的个数

(在此可以类比十进制1011,由1个1000,0个100,1个10,1个1组成。)

所以,二进制数1011由1个8,0个4,1个2,1个1组成。按各位的权列出:

{1011}_{2}=1\times{2}^{3}+0\times2^{2}+1\times2^{1}+1\times2^{0}

按这种权展开式可以很方便将二进制转换为十进制。


相应的,十进制转换成二进制整数就通常采用“除2取余,逆序排列”的方法。具体做法是用2整除十进制整数,可以得到一个商和余数,再用2去除商,又会得到一个商和余数,如此反复,直到商为0停止。再把先得到的余数作为二进制低位有效位,后得到的余数作为二进制高位有效位,依次排列。

举个栗子:

将十进制“11”转换为二进制。

将十进制11转换为二进制数为1011。


和十进制相比,二进制的运算规则也就简单多了。

加法

二进制运算只会有以下4种可能

0+0=0

0+1=1

1+0=1

1+1=10

(逢二进一)

对于多位数二进制相加,考虑进位采用“逢2进1”的方式,例如十进制25(二进制11001)加上十进制27(二进制11011):

减法

也只有4种可能:

0-0=0

1-0=1

1-1=0

0-1=1

(借一当二)

乘法

十进制可以按照九九乘法表运算,二进制乘法规则就简单多了,也有4种情况:

0\times0=0

1\times0=0

0\times1=0

1\times1=1

二进制乘法也可以很简单转换为加法运算,例如十进制25(二进制11001)乘以十进制5(二进制101)。

除法

除法是乘法的逆运算,二进制乘法有4种,除法也是应该对应4种,考虑0作为除数是没有意义的。所以除法有以下两种:

0\div1=0

1\div1=1

例如十进制25(二进制11001)除以十进制5(二进制101)。

比较复杂的乘法和除法运算都能简单的转换为加、减和位移操作,所以一般计算机也只需要设计一个加法器即可。


二进制弄清楚了,八进制也就很好懂了。

其实很早,古人就明白了八进制的概念,比如八卦...

八卦最初就是古人的记事符号,只是后来作为占卜工具被打上封建迷信的标志。

其中隐含着二进制和八进制的概念。

八卦的基本元素就是阴和阳,相当于二进制中的0和1。

下图中用长实线代表“阳”,用中间断开的线代表“阴”,然后由3种这样的线条组成8种形状,相当于3位二进制数表示8种状态。

当然,八进制计数不可能用八卦表示,通常采用0-7的阿拉伯数字表示

八进制的计数规则:

  • 基数为8。
  • 由8个数字组成,分别是0、1、2、3、4、5、6、7。
  • 逢8进1,借1当8。


十六进制,在古代中国当时使用的重量单位就是十六进制,16两为1斤,就有了所谓的“半斤八两”。

同样十六进制的计数规则为:

  • 基数为16。
  • 由16个数字符号组成,分别是0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、F。
  • 逢16进1,借1当16。

各种进制的转换

前面二进制和十进制相互转换的方法,同样适用于其他进制的数转换为十进制。

“按权展开”—其他进制转换为十进制(B表示各进制的基数,n表示位数):

A=X_{n-1} B^{n-1} +X_{n-2} B^{n-2}+...+X_{1} B^{1} +X_{0} B^{0}

例如十六进制数BC0D转换为十进制:

\left( BC0D \right) _{16} =11\times 16^{(4-1)}+ 12\times 16^{(3-1)}+0\times 16^{(2-1)}+13\times 16^{(1-1)}=48141

“除基数B取余,逆序排列”方法可以将十进制数转换为任意进制数。


二进制和八进制、十六进制数的转换可以采用更简单的方法。

二进制转换为八进制,采用“3位并1位”,按从右向左方向,每3位二进制位一组,最高位不足3位,添0补足3位,然后将各组3位二进制数加权展开,得到八进制数。

\left( 1101001101110011 \right) _{2} =\left( 151563 \right) _{8}\frac{001}{1} \frac{101}{5} \frac{001}{1} \frac{101}{5} \frac{110}{6} \frac{011}{3}

将八进制转换为二进制采用相反的操作“1位拆3位”。

类似的,十六进制和二进制转换为“4位并1位”,“1位拆4位”的方法,在此就不再啰嗦了。

如果大家不是很想自己手算进制的话,这里推荐一款微信小程序“小算包”(当初闲时写的)也可以协助计算。

我们先思考一下,如何用有限的符号表达一个很大的数字?例如我们有阿拉伯数字 0~9,那么我们可以用这个集合内的符号表达 0~9 范围内的数。那么我们如何表达十百乃至千万呢?

可以想到的,也是我们现在正在使用的做法是,把大数拆成多个部分,每个部分都可以用我们现有的符号表示,这些符号再通过一定的组合方式就可以还原原来的大数。至于为什么不用更多符号……多麻烦啊。

拆分的方法是,首先设置一个数作为进制数,然后用大数反复除以这个进制数,把每一次除法的商和余数记录下来,然后用定位原理就可以表示这个数。

打个比方,我们有一堆围棋棋子,但是它的数量远远超过我们用一个符号能表示的范围。我们就要设计一套可以通过我们已有的符号来表示它的数量的方法。为什么要用棋子……因为便宜啊,而且形状规整容易计数。

首先我们要设置一个进制数。例如我们一只手有五根手指,那就用五进制好了。接下来我们要用五去除这堆棋子数,于是我们找来五个筐。我们每一轮把这堆棋子依次往每个筐里放入一枚,确保这一轮操作结束之后,每个筐里的棋子数量是一样多的。

进行了若干轮之后,五个筐里分别装了许多棋子。我们发现接下来的棋子数量只有 3 枚,下一轮不够放了。那么我们就先暂停放棋子的步骤,把 3 这个数字记下来。接下来我们来看每个筐,筐里面的棋子数量还是多得超过我们的符号范围,但是我们可以确定的是,因为每个筐里棋子的数量相同,那么我们就可以根据一个对应关系(例如在每颗棋子上面做标记,然后统计它们进入筐里的顺序)将每颗棋子与其它几个筐里的棋子一一对应起来,这样我们就可以用一个筐里的棋子数目来表示五个筐。于是我们把多出来的 3 枚棋子和四个筐里的棋子倒出来放到一边,然后把剩下这一筐的棋子拿出来,继续平均放到五个筐里去。分到最后多出来 2 枚棋子,然后看筐里,运气不错,每个筐里都有 1 枚棋子,这个数我们就可以用我们的符号来表示了。

这一系列步骤中我们依次得到了三个数字,3,2 和 1。这三个数字的意义显然不一样。它们的意义分别是什么呢?

第一个 3 表示,对于我们要表示的大数,用五去除,余数是 3。第二个 2 表示,对于上一步得到的商,我们继续用五去除,余数是 2。注意这个余数和上一步的 3 是不同的:这个 2 代表的不是 2 枚棋子,而是这枚棋子本身以及它和其它四个筐里与它一一对应的另外四枚棋子,也就是五枚。换言之这个余数代表的意义其实是 2×5。最后一个 1 的意义是,其实如果我们再做一步除法的话,结果是第一轮就结束——筐里没有棋子,然后余数是 1。然后这个 1 对应的,是第二轮中的五枚棋子,以及这五枚棋子在第一轮中所对应的 5×5 枚棋子。

实际上我们可以注意到,在每一步除法中,每一枚棋子的意义都不一样。一开始它们只对应自己,再往后它们就对应了多枚棋子。这正是定位计数法的重要特征:数字的意义与其所在的位置有关。对于 3,2 和 1 这三个数字,1 对应的数最大,其次是 2,最后是 3。那么我们把它们并排写在一起,然后把我们使用的进制数标记出来,就得到了这堆棋子的数量:(123)_{5} 枚。

我们强调定位计数法是因为有的计数法并不是采用这样的位置关系,典型如罗马数字。

那么我们有一个用这个表示法表示出来的数字了,我们要怎么还原它的值呢?

例如十进制下的 333,虽然三个都是数字 3,但根据我们标记这个数步骤,它们的意义是不同的。最后一个 3 表示这个数中含有 3 个 10^{0},即找来十个筐投棋子,第一次有 3 个多出来;第二个 3 表示这个数中含有 3 个 10^{1};第一个 3 表示这个数中含有 3 个 10^{2}。那么这个数的大小,就是3\times10^{2}\,+\,3\times10^{1}\,+\,3\times10^{0}\,=\,333

为什么是 10 呢?因为我们这里举的例子是十进制。我们也可以换用别的进制来看看。

同样是 333,现在我们规定这是个七进制下的 333,即 (333)_{7}。那么这三个数字的意义就改变了。最后一个 3 表示这个数中含有 3 个 7^{0},第二个 3 表示这个数中含有 3 个 7^{1},第一个 3 表示这个数中含有 3 个 7^{2}。于是这个数就是3\times7^{2}\,+\,3\times7^{1}\,+\,3\times7^{0}\,=\,(333)_{7}。之前我们得到的 (123)_{5} 的意义即 1\times5^{2}\,+\,2\times5^{1}\,+\,3\times5^{0}\,=\,(123)_{5}

最难的骨头吃掉了下面的就轻松加愉快了。

进制之间的想互转换,说白了就是上面我们表示以及还原一个数的过程。反复除以进制数,把每一步的余数从大到小列出来,就是新进制下的数。二进制的意思是,我们只有两个筐。也就是说我们分棋子能得到的余数,要么是 1,要么是 0。也即二进制计数只有 0 和 1 两个数字。八进制即 0~7。十六进制的话超过了阿拉伯数字的范围,我们就把字母 A~F 借来。反正这个只是符号而已,它的意义是它背后的数。

不过值得注意的是,因为 2^{3}\,=\,82^{4}\,=\,16,所以二进制与八进制、十六进制之间的转换非常方便。把一串二进制数字从后往前三位划为一组,然后把每一组视作进制数的话,这个进制数就是 2^{3}\,=\,8。同理从后往前四位一组,每一组就是 16。所以我们只要准备一张换算表格,就能在二进制与八进制、十六进制之间快速转换:

Bin Oct
--------
000   0
001   1
010   2
011   3
100   4
101   5
110   6
111   7

十六进制同理。

所以二、八、十、十六四种进制之间的转换,简单来说就是通通以二进制作为跳板。

我大概讲清楚了吧。谢捧场。

Bonus:

计算机用电气信号表示二进制很方便这不用多说;在一些低级语言的开发中,倒是有定位原理的体现。

例如 AVR 开发板有一个数字键盘。获取数字键盘输入的做法大致是轮询……这个也不多说了。我们每按下一个数字,它就会向系统返回一个信号。那么我们要如何确保依次按下 123,它会返回我们需要的数一百二十三,而不是一个简单的字符串 “123” ?

答案是,当输入一个数字的时候,就把前面输入的数乘以十,再加上新鲜输入的这个数。