二进制

二进制

世界上有10种人,一种是懂二进制的,另一种是不懂二进制的。


什么?你没看懂?那你就是上面说的第10种人。


这里的10,跟我们平常说的10不是一个意思。平常我们说的10,是十进制的十。十进制是人类用得最普遍的一种进制。为什么呢?因为人类有十个手指嘛(滑稽)。想想在遥远的史前时代,智人祖先爸爸们打猎归来,智人祖先妈妈要数数爸爸们总共打了多少只兔子,最简单的办法就是掰手指。来来来,爸爸一号,3只兔子(掰手指):1,2,3;爸爸二号,5只兔子(掰手指):4,5,6,7,8;爸爸三号,4只兔子(掰手指):9,10...哎呀嗬,手指不够用了!怎么办?爸爸三号对不住,剩下两只你拿去扔了吧,晚饭没你的份儿了。

可以,这很OK


爸爸三号肯定不干啊。

“不行你再数数”

“怎么数?我手指都用完了怎么数?要不你借我几根?”

“借你就借你,借几根手指能怀孕还是怎么着。”爸爸三号说,“不过我的手指跟你的可不一样,我这一根手指顶你的十根。我掰一根手指,就表示你十根手指用完一次了,这样你的手指就可以解放出来数新的一轮了。”

"哎呦不错哦,看不出来你这么聪明啊。从明天开始你就是一号了。那谁,打兔子最少那个,不用看了就是你,别人四只五只就你三只是不是最少自己心里没点(bi)数吗?从明天开始你是三号。“

就这样,爸爸三号上位成功。并且发明了计数系统中最伟大的“进位”思想。


所谓“进位”,就是为单个数字赋予高权重来表示更大数字的做法。这也引入了计数系统中“位”的概念,在不同“位”上的数字,权重是不一样的,这就是所谓的“位高权重”。在十进制中,高位数字的权重是相邻低位数字权重的十倍,第n位数字的权重是十的(n-1)次方(10^(n-1))。为什么十进制的权重是乘十递增呢?因为十进制里有且仅有十个基本计数符号。十个符号用完以后才需要进位,高位1个单位,表示的是低位已经用完的十个单位,因此进位基础是十,权重也是乘十递增。


计数系统的本质就是用有限的基本计数符号来表示无限多的数。前面说的“数字”其实是不准确的,准确的说法是“基本计数符号”。所谓进制就是用来描述计数系统基本计数符号个数的。某种进制的基本计数符号如果有n个,这种进制就被称作n进制。该进制的基本计数符号个数称作该进制的“基数”(radix)或者“底数”(base)。比如,二进制的基本计数符号有两个,二进制的基数(底数)就是2。十进制的基本计数符号有10个,十进制的基数(底数)就是10。


注意哦,“基本计数符号的个数是多少”,跟”基本计数符号有哪些“,是两个不同的层次的问题。“基本计数符号的个数”决定计数系统的进制,“基本计数符号的集合”决定计数系统如何书写和表达。比如,十进制的基本计数符号有十个,这十个符号可以是十根手指,可以是”0, 1, 2, 3, 4, 5, 6, 7, 8, 9“,也可以是”〇,一,二,三,四,五,六,七,八,九“,还可以是“零,壹,贰,叁,肆,伍,陆,柒,捌,玖”,甚至可以是“૦,૧,૨,૩,૪,૫,૬,૭,૮,૯”(古吉拉特数字)。不管基本计数符号怎么变,只要总数是10个,就不改变它十进制的本质。

数字系统


现在终于可以解释本文开头的那句话了。“世界上有10种人,一种是懂二进制的,另一种是不懂二进制的。”这里的10,是二进制的(10)2。二进制里只有两个基本计数符号,通常写成0和1。那么二进制里要表示二怎么办?进位呀!爸爸三号的智慧这里不就用上了吗——十进制里满十进一,二进制就是满二进一。进位以后,高位记1,低位清0,所以就是“10”。二进制里怎么表示“三”呢?10+1,所以是(11)2。怎么表示“四”呢?11+1,又该进位了,进了一位不过瘾,还得再进一位,结果是(100)2。


说到这里又可以插播一个段子。话说某位程序员姓伊,某一年喜得千金,取名“伊玲依”。

第二年又得千金,取名“伊依玲”。

第三年又得千金,取名“伊依依”。

第四年生了个大胖儿子,只好取名“伊忆初”。


为什么儿子要叫忆初呢?是不是他重男轻女?男孩就不按规矩来编码了?其实不是的。因为在位数确定的情况下,任何进制所能表达的数都是有取值范围的。比如,两位十进制数,能表示的最大整数是99。二进制因为只有两个基本计数符号,每一位的容量很小,因此表达范围也比十进制小很多。同样是两位数,二进制能表示的最大数是(11)2,相当于十进制的三。这哥们一口气生了四个孩子,可不就“溢出”了嘛。理论上说,m位n进制数,能表示的最大整数就是n的m次方减1(n^m-1)。比如,三位十进制数,能表示的最大整数是十的三次方减1,就是999。三位二进制数,能表示的最大整数是二的三次方减1,就是(111)2,相当于十进制的7。

我们通常说计算机有多少“位”,说的就是这个二进制位。所以32位的计算机,硬件层面能表示的最大整数是二的32次方减1(2^32-1),转换成十进制数是4294967295,也就四十二亿多。刚查了下A股,中石化今天的交易额是49.69亿。也就是说,如果纯用硬件表示,32位的计算机连计算中石化一天的股票交易额都够呛。好在有各种码农开发了各种库,从软件层面实现了大数计算,解决了硬件位数不够的问题。另外,现在主流计算机都是64位了,64位二进制数能表示的最大整数是2的64次方减1(2^64-1),转换成十进制数大概是10的19次方,这个数日常生活已经足够用了(2017年全球GDP总量约80万亿美元,也就10的14次方这个量级)。当然如果你要经常计算阿伏伽德罗常数什么的则另说。


至于二进制数的计算(手算),最简单的办法是转换成十进制进行计算,算完的结果再转回二进制。但是其实完全不经过中间转换,直接用十进制的规则来计算也是没问题的。唯一要注意的是,二进制里只有0和1,做加法的时候低位满2进1,做减法的时候向高位借1当2。至于乘法和除法,二进制的乘除法手算规则跟十进制一!毛!一!样!这是为什么呢?大家想想,我们手算十进制乘除法的基础是什么?是九九乘法表。“一一得一,一二得二,一三得三……九九八十一”。对于二进制,也有一个“一一乘法表”,只用背一句口诀:

"一一得一"

这tm还用背?

坑爹呢这是

当然不用背。关键在于,这个“一一乘法表”,完全就是“九九乘法表”的子集啊!

有同学可能要说,这有什么好惊讶的,难道在别的进制下,乘法表就不是九九乘法表的子集了吗?这个还真不是。

我们先来看看三进制的“二二乘法表”(三进制有0,1,2三个基本计数符号):

"一一得一,一二得二,二一得二,二二十一“

前面三句都还正常,最后一句“二二十一”什么鬼?

因为在三进制里,没有“3”和“4”,十进制的三只能记作(10)3,十进制的四只能记作(11)3,十进制的五是(12)3,六则是(20)3。

类似的,四进制的”三三乘法表“里有”二二一十“这种奇葩:(2)4*(2)4=(10)4。

五进制的”四四乘法表“必然会有”二三十一“:(2)5*(3)5=(11)5。

……

十六进制的“FF乘法表”里会有“八九四十八”,“AB六十E”,“FFE十一”(十六进制有十六个基本计数符号:0,1,2,3,4,5,6,7,8,9,A,B,C,D,E,F。十六进制下,(8)16*(9)16=(48)16,(A)16*(B)16=(6E)16,(F)16*(F)16=(E1)16)。

看你们这些奇葩进制一个个练功走火入魔的样子,我二进制的脸上露出了一丝冷笑。

冷笑


正是因为二进制的乘法表是十进制乘法表的真·子集,二进制乘除法计算才会显得无比和谐:

(101)2*(100)2=(10100)2,(101)2*(11)2=(1111)2,(101101)2/(101)2=(1001)2

这些式子,直接用十进制的规则计算,结果跟用二进制规则计算是一毛一样的。

当然也有特殊情况:

十进制:101*101=10201,二进制:(101)2*(101)2=(11001)2。

但这只是加减进位的问题,把十进制结果中间的“02”替换成二进制的“10”,结果还是一毛一样。

简直完美。


二进制的另一个完美之处在于:它跟逻辑运算可以无缝结合。逻辑运算操作数集合有两个元素,true和false,二进制也只有两个基本计数符号,1和0。如果用1表示true,0表示false,我们来看看一位二进制数的计算情况:

加法(不考虑进位): 逻辑异或:

0+0=0----------------->0⊕0=0

0+1=1------------------>0⊕1=1

1+0=1------------------>1⊕0=1

1+1=0------------------>1⊕1=0

减法(不考虑借位): 逻辑异或:

0-0=0------------------>0⊕0=0

0-1=1------------------>0⊕1=1

1-0=1------------------>1⊕0=1

1-1=0------------------>1⊕1=0

乘法(不考虑进位): 逻辑与:

0*0=0------------------>0∧0=0

0*1=0------------------>0∧1=0

1*0=0------------------>1∧0=0

1*1=1------------------>1∧1=1

简直一拍即合啊有没有!(CPU计算除法用的是跟乘法类似的逻辑,这里不展开)


由于二进制的这些特性,它成为了计算机基础计算的不二之选。逻辑运算是计算机科学的软件基础,门电路作为逻辑运算的物理表达,本来只能进行逻辑真假的计算。二进制的采用,使得算术计算能够以二进制的方式转换为逻辑运算,从而让门电路有了构建数字世界的可能。抛开物质的本质不谈(这是个哲学问题),从某种意义上说,我们所生活的世界就是一堆数字的集合。把这些数字拆解,计算,重建,才有了我们今天所看到的无穷无尽的软件,游戏,音乐,电影,app,才有了信息技术革命和互联网的大发展。

编辑于 2018-06-02

文章被以下专栏收录