一、引子
从这个小节开始,我们会正式进入第五章的内容,开始学习数据的表示和运算。
通过第一章的学习,我们知道了现代的计算机大致上可以分为这样的五大部件。
主存储器可以用来存放数据,而运算器可以对数据进行数学运算或者逻辑运算。所以我们该死的求知欲告诉我们,接下来我们应该探究的问题是数据应该怎么在计算机当中表示,也就是如何用二进制来表示。
另外一个问题就是运算器是怎么实现数据的这些算数和逻辑运算的。
这就是这一章要探讨的两大主题。
这一小节我们首先要学习什么是进位计数制。
平时我们使用的是 10 进制数,而计算机能够识别的是二进制数,为了方便我们程序员来阅读或者记录,我们在计算机专业里边通常还会使用到8进制和 16 进制数。
这一小节包含一些重要的考点,其实就是各种数制之间的转换。 2 进制、 8 进制、 16 进制如何转换成 10 进制?还有 10 进制怎么来转换成 2 进制、 8 进制、 16 进制。
另外 2、8、16 这三种进制数之间又有一些比较特殊的联系,所以这三种进制之间的转换我们会放在中间单独的讲解。
最后我们还会介绍两个简单的概念,分别是真值还有机器数。
二、计数方法
我们首先进入第一个话题。
(1)最古老计数方法
来看一下人类最古老最原始的一种计数方法。
数字其实和人类的生产活动是息息相关的,在人类还处于原始部落阶段的时候,部落里的人出去摘果子,他们会用比如画竖线或者画横线的方式来记录每一个人摘了多少个果子。
一条竖线就会对应一个苹果,这就是最原始的技术方式。
但是慢慢的人们发现这种技术方式的一个缺点就是,没办法记录苹果数量很多的情况。
所以后来就有一些远古的祖先们发现了,可以用不同的符号来表示不同的数量。
比如我们可以用一个横线来表示 5 个苹果,而每一条竖线表示的是1个苹果,所以 8 个苹果可以表示成这样的形式。
而 17 个苹果就可以用3个横线加2条竖线来表示。
这就是最原始的一种计数方式,不同的符号会反映不同的权重
。
横线的权重是5,竖线的权重是1。
(2)罗马数字
基于这种思想所发明的最著名的一种计数方式就是罗马数字
。
在罗马数字中, i 可以表示1, v 表示 5,X 表示10。l、c、d、 m 分别表示不同的权值。
所以我们现在也会经常使用到罗马数字。
当然了,在中世纪之后, 4 的表示方式一般是写成一个i,再加一个v,这是表示4。如果要表示5,就是一个v,因为 v 符号的权重就是5。
总之,这种计数方式的基本思想就是,不同的符号会反映不同的权重。
我们要把这些符号转换成实际的数值,其实做的都是加法的操作。一个 m 表示的是1000,再加上一个 d 表示的是500,再加上 3 个c,也分别加上 3 个100,以此类推。
这种单纯用符号来反映权重的计数方法显然是存在缺点的。如果我们要表示的数字不断增大,我们就有可能需要发明更多的符号。
比如想表示1万,我们可能会发明一个符号叫w,你想表示 10 万,可能还需要发明一个符号叫 y 之类的。
随着人类生产活动的发展,人类想要表示的数字会越来越大,采用罗马数字的这种计数方法,就会产生很多的不方便。
(3)十进制计数法
后来聪明的古印度人发明了阿拉伯数字
。
1.整数
是的,你没有看错,阿拉伯数字其实是古印度人发明的,只不过是由阿拉伯人传入欧洲,所以欧洲人以为是阿拉伯人发明的。
阿拉伯数字总共会有 10 种不同的符号,每一个符号会反映不同的权重,会代表不一样的实际数值。
另外,他们还发明了我们现在最常使用的十进制计数系统。
这种计数方式除了会用符号来反映权重之外,符号它所在的位置也会反映权重。
比如 975 这样的一个十进制数,其实它的 5
这个数权重应该是乘以1,7
这个数应该是乘以 10 的权重,而 9
这个数要乘以 100 的权重。
每一个数码位,它所处的位置不同,它所表示的权重就不一样。
用中国古人的话来讲,就是个、十、百这几个位,我们可以把各个数码位的权重换一种表示方式。
个位其实是相当于它的权重是 10 的 0 次方,十位表示的是 10 的 1 次方,百位它的权重应该是 10 的2次方。以此类推。
总之,十进制的这种计数方式,我们会用每一个数码位乘以数码位所对应的一个实际的权值,这些权值都是 10 的某次方,因此我们才把它叫做十进制。
2.小数
975 这个数,它只是一个整数,如果它带小数,其实原理也是类似的。比如:
每一个数码位,它所在的位置不同,它的权值,它的权重也会不一样。
最高位的小数,它的权值应该是 10 的负 1 次方,第二个小数应该是 10 的负二次方,以此类推。
可以看到这种十进制的计数方式和罗马计数方式的思想是不一样的,这里引入了乘法的思想,每个符号所表示的数值不一样,权重不一样。
另外,符号所在的位置也会直接的反映这个符号的权重。
那由每一个符号它所处的位置所确定的权值(权重)。我们把这个东西称为位权
,由位置确定的权重,所以叫位权。
可以想一下,为什么我们人类通常都习惯于使用十进制这种计数方法。其实很大一部分原因是人是拥有 10 根手指的。
比如我们可以用这样的手势表示 8 数,用这样的手势表示10,总共有 10 根手指。
在我小的时候,我会和院子里其他小伙伴打篮球,我们会派两个人来负责记分,其中一个人记录的是个位的分。当进球数量达到 10 个之后,是不是手指就不够用了?此时就需要另一个小伙伴伸出他的一根手指,用来表示这一波人进了 10 分。记录个位分数的这双小手是不是又可以恢复成 0 的状态?从 0 开始,1234567,这样往上加。
总之,由于我们人类只有 10 根手指,因此当我们在数数的时候,逢10进1,这样的思想应该是最符合人类习惯的。
所以这也是为什么叫十进制的原因。当我们进行加法的时候,每当加到10,就可以往高位进一个数,逢10进1。人类有 10 根手指,所以自然而然的能够想到逢10进1。
这不禁让我想到,也许我们八进制的发明者是海绵宝宝,因为它只有 8 根手指,如果让他数数,肯定逢 8 进1,会比较符合他的身体构造。
(4)r 进制计数法
1.r 进制
接下来我们把十进制的基础方式推广到 r 进制
。
首先我们要引入一个概念,叫做基数
。
每一个数码位所用到的不同的符号的个数,就是所谓的基数。
比如十进制在每一个数码位有可能用到的符号会有0、1、2,一直到9,总共有 10 种符号。
那对于一个 r 进制的数来说,它的基数应该是r,也就是有可能会出现 r 种不一样的符号。
比如在古巴比伦时期,人们会使用到 60 进制,每一个数码位有可能会出现 60 种不一样的符号。
即便在现代社会, 60 进制的使用依然是十分广泛的。比如对于时间的记录,人们经常会使用到 60 进制,因为一个小时会被我们拆分成 60 分钟。这其实和早期的人类文明就发明了 60 进制是有一定关系的。
不过对于我们计算机世界来说,我们不需要关心60 进制。计算机世界当中通常使用到的是 2 进制、 8 进制和 16 进制。
①对于二进制
的数来说,每一个数码位只有可能出现 2 种符号,一种是0,另一种是1。
②对于八进制
来说,每一个数码位有可能出现 8 种符号,分别是 0- 7。
③对于十六进制
来说,每个数码位有可能出现 16 种符号, 0- 9这儿总共有 10 个我们常用的符号,如果还要再增加,还不够 6 个怎么办?我们用字母来代替。 所以十六进制数当中, a 这样的一个符号,其实它表示的是 10 这个数, b 表示的是11, c 表示的是12,一直到 f 表示的是15。
2.r 进制转为十进制
我们下面这个式子,其实就给出了各种进制转换成我们熟悉的十进制数的转换方式。
不同的数码位在不同的位置有不一样的位权,你用每一个数码位的值乘以它在这个位置的位权,再相乘相加,就可以轻松地转换成十进制。
<1> 二进制
转化为十进制
① 101.1
小数点前边的第一位,它的权重应该是 r 的零次方,也就是2的零次方,这一位的数值就是1;第二位是0,权重是 2 的一次方;第三位值是1,权重是 2 的二次方。
还有小数点后的一位,这一位的权重应该是 2 的负一次方。
所以把每一个数码位的数值,还有数码位的位权进行相乘相加,就可以得到二进制数它所对应的十进制的数值。
②10010010.110
可以看到,二进制的 K0 位是0, K1位是1......而小数部分, K 的- 1 位是 1,K的- 2 位也是1。
所以我们只需要把数码位为 1 的这些部分进行一个相乘相加就可以了。
最终算得的结果应该是对应十进制的 146. 75 。
二进制想要转换成十进制,还有一种方法,如果你能熟练地记住每一个二进制位它的权值是多少,转换是很方便的。
二进制数的整数最低位的权值应该是 2 的 0 次方,也就是1。第二位的权值应该是2,接下来第三位的权值应该是4。 然后是8、16、32、64、128 。
小数部分的最高位权值是 0. 5,接下来是 0. 25,再接下来是 0. 125。
我们再把二进制数和各个位的权值对应上,所以这个二进制数的实际数值应该是128,加上16,再加上2,再加上 0. 5,再加 0. 25,加得的结果也是 146. 75。
这是我个人比较喜欢的一种转换方法。我会先把各个位的位权按照顺序写下来,再把二进制数给它对应上去。这样就不需要思考 2 的 7 次方到底是多少, 2 的 4 次方到底是多少。
所以大家可以记一下这个东西,每一位的位权分别是多少。这是二进制转换成十进制。
<2> 八进制
转为十进制
①5.4。
小数点前的数是5,这个数的权值应该是 r 的 0 次方,所以这儿乘以 8 的 0 次方,也就乘以1。
小数点后的这一位数值是4,再乘以它的位权 8 的负一次方,就可以得到八进制数 5. 4,它所对应的十进制数值是 5. 5。
②251.5
八进制转换成十进制我们就不再赘述,反正就是用每一个数码位乘以这个位的位权相乘再相加,最终得到八进制所对应的十进制数168.625。
<3> 十进制数
我们不必多说。如下:
<4> 十六进制数
转为十进制
①5.8
小数点前的这一位数值是 5, 位权是 16 的 0 次方。
小数点后的这一位是8,它的位权应该是 16 的- 1 次方。所以转换成与之对应的十进制,同样也是 5. 5。
②AE86.1
A这个字母它表示的其实是10,而E应该是14,大家可以自己数一下。
最终转换成十进制应该是这样的一个值。
对于计算机专业的同学,这些问题应该是很简单很熟悉的,而跨考的同学可以自己多动手练习一下,也可以自己给自己随便写一些数字转换成十进制。
好,这是任意进制转到十进制。
3.十进制转换为r 进制
接下来我们探讨一个问题,就是十进制如何转变为其他进制。
比如 75. 3,这是一个十进制数,需要把它转换成其他进制,我们需要分为整数部分和小数部分来分别进行处理。
<1> 十进制转换为二进制
①首先我们来处理整数部分75。
通过之前 r 进制和十进制相互对应的公式,我们可以知道,用 r 进制来表示整数部分,应该是这样的一个值,这个值刚好就等于75。如下:
如果我们对整数部分的表达式统一除以一个基数r,就可以得到这样的一个结果。
前面这个部分就是除法的商,而后边会得到一个余数K0。
解释一下。
我们把商记作X,所以原本我们放在分子的部分,可以把它写成 r 乘以X,再加上 K0 乘以 r 的 0 次方,而 r 的 0 次方应该是等于1,所以直接加上一个K0。
现在对于 r 进制的这种计数方法来说,任何一个数码位的值应该是 0 ~ r-1
这样的一个范围,也就是 K0 的值肯定也是 0 ~ r-1
这样的一个范围。
因此,上边除式我们用 rX 加 K 0 除以一个r,我们得到的商应该是X。 一相减得到的余数就是 K0。因为 K0 小于r,所以它肯定是一个余数。
这就是刚才这个结论的由来,是因为我们任何一个数码位 k 肯定是小于 r 的,所以我们一除,最终得到的余数肯定是K0。
求得了 K0 是不是就意味着我们已经得知了用 r 进制数表示 75 的时候,最低的整数位是多少,已经得到这个整数位的值。
接下来我们怎么得到 K1 的值?
是不是也是一样的原理,我们用之前得到的商再除以一次r,这次除法所得到的余数是不是就是K1?原理和之前是一样的。
因此我们基于这样的原理,把 75 转换成与之对应的二进制数。
二进制的基数 r 等于2,所以首先 75/ 2 商是37,余数是1。
根据刚才的推论,余数 1 就是K0。
接下来用刚才得到的商再除以r,得到商是18,余数是11,对应的应该是 K1 的值。
继续往后是不是一样的,每一次用上一步得到的商再除以基数r,用这样的方式一直到商为 0 为止。
每一步除法得到的余数就对应了二进制数当中一个一个的数码位,先得到的余数是低位的,后得到的余数应该是处于高位的。如下:
当然了,如果我们做题的时候用这种写法会很费纸张,所以我们一般会用短除法
的方式。
75 除以2得到 37 余 1,37 再除以2得到 18 余1,以此类推。
用这种短除法的记录方式会更直观一些。
最初得到的余数应该是K0,也就是低位,最后得到的余数应该是处于高位。
由于每一步我们都会除以基数r,并且我们会取余数作为最终的结果,因此这种方法叫做除积取余法。
所以刚才 75 这个十进制转换成与之对应的二进制,应该是1001011,从高到低。
当然也可以记录成这样的方式75D=1001011B
,用 D 表示十进制,用 B 表示二进制。
②接下来看小数部分0.3怎么处理,也就是我们这标蓝的这些部分。
注意观察会发现,小数部分的值 0. 3 应该是可以表示成这样的一个式子。
对这个式子乘以一个基数r,可以得到这样的一个值。
因此,我们用小数部分乘以基数 r 得到的乘积结果的整数部分就是 k(-1) 的值。
接下来计算 K (-2) 也是一样,再对剩下的小数部分乘以基数r,第二次的乘法,所得到的整数部分就是 k(-2)的值。
所以 0. 3 转换成二进制奇,基数 r 等于 2。
- 3乘以 2 等于0. 6。 整数部分是
0
,小数部分是.6
,所以整数部分对应的就是 k (-1)。
接下来,根据刚才的推论,把刚才得到的小数部分0.6再乘以2,得到 1. 2,因此整数部分 1 应该是 k (-2)。
以此类推。
我们会发现,用这样的方式进行几轮乘法之后,最后又回到了小数部分为 0. 6 的情况。
也就是说,你还可以继续往下乘,得到更多的二进制。
这其实意味着,我们用十进制表示的 0. 3 这个数,没办法用二进制数来精确地表示。
我们的转换过程就到此为止,精度是精确到二进制数小数点后的5个位。
如果精度不够,你继续往后求。,可想而知,0. 3 这个数用二进制来表示,应该是 0. 01001,后面又是01001、01001,无限循环下去。
只能不断地趋近0.3,而不能无误差地表示0.3。
同样的,这种记录方式比较麻烦,需要写比较多的东西,我们可以把它改进一下。
0.3乘以2等于0.6,这儿我们把它记录下,第一个整数0。
接下来, 0. 6 乘以2,得 1. 2,记录下整数1。
接下来用小数 0. 2 再乘以2,以此类推。
我们最先得到的 0 应该是小数部分的高位,越靠后出现的应该是越低位。
由于这种方法,我们每一次会乘以基数,最终取整数的部分,所以这种方法叫做乘积取整法
。
<2> 十进制转换为八进制
①整数部分75
如果要把它转换成八进制,也是一样的。
只不过我们把这儿的基 r 变成 8 就可以了。
同样可以用除积取余法把十进制转换成八进制。
当然还有一种方式是,你可以先把它转换成你最熟悉的二进制,二进制再转换成八进制,因为 2 转换成 8 很容易。
同样,这样算更加简便:
这是对于整数部分的一个处理。
②小数部分0.3
和之前方法一致,不做过多赘述。
简便计算:
<3> 拼凑法
所以十进制转换成其他进制,我们需要分为整数部分和小数部分来分别进行处理。
整数部分我们要用除积取余法,而小数部分我们用乘积取整法。
如果大家能够熟练地记住,或者在稿纸上先提前写出每一个二进制位,它所对应的位权是多少。其实我们也可以用拼凑
的方式把十进制转换成二进制。
①260.75
比如对于260.75这样的一个数,我们先来看整数部分, 260 应该是等于256再加上 44 ,应该是这个位置。
所以整数部分很显然应该是100000100
,这是整数部分。
而小数部分是0.75,0.75刚好是等于0.5加0.25,所以小数部分应该是.11
。
所以用这种方式可以更快的把某一些十进制数转换成二进制。
②533.125
第二个例子也是一样的, 533. 125。
首先看整数部分, 533 应该是125再加上21,21又可以用16再拼上 5 ,5再拼一个4和1。
所以 533 十进制数转换成二进制肯定是1000010101
,这是整数部分。
小数部分.125 刚好是 2 的- 3 次方,所以小数部分应该是.001
。
所以这样我们就快速的把十进制转换成了二进制。
如果题目要求你把十进制转换成八进制或者十六进制,你在熟悉这种方法之后,完全可以先转换成二进制,二进制再转成八进制或者十六进制,就会很方便。
来试一下。
比如把刚才的十进制数533.125转换成八进制。
十进制533.125转换为二进制就是1000010101.001。
三位为一组, 101 对应的应该是5;010对应的是2;000 对应的应该是0,最后的 1前面再补两个0,它所对应的八进制是1。
小数点后的三位 001 对应的应该是八进制的1。
所以如果把它转换成八进制就是 1025. 1。
个人认为如果它给你的十进制数不是特别大,用这种拼拼凑凑的方法反而会转换的更快一些。
我们不一定非要跟着课本上的方法来做。
4.r 进制加法
<1> 八进制加法
如果八进制数 5. 4加上八进制数 1. 4,结果应该等于多少呢?
这个加法的运算其实和十进制的运算是一样的。
小数点后的这两位 4 + 4 = 8。但是需要注意,由于我们采用的是八进制,所以逢 8 应该进一。
因此对于八进制来说,八进制的 0. 4 + 0. 4 应该是刚好等于 1. 0,逢 8 进1。
小数这儿保留0,然后往整数位进1,整数位应该是 5 + 1,再加 1 就等于 7 还没有到8,所以 5. 4 + 1. 4 应该是等于 7. 0。
这个是基于八进制的一个加法。如下:
<2>十六进制
对于十六进制也是类似的,我们需要逢 16 进一。
比如十六进制数 5. 8,加上十六进制数 0. 9。
小数部分 8 + 9 应该是等于17, 17 可以表示为 16 + 1,逢 16 进1,因此应该往整数部分进一,小数部分只留下1。
接下来是整数部分的加法计算。 5 + 0 + 1 应该是等于6,所以 5. 8 十六进制加上 0. 9,十六进制应该是等于 6. 1。
我们要遵循逢十六进一的原则。如下:
<3> 二进制加法
我们再来举一个二进制加法的简单例子。
二进制数 101. 1,加上另外一个二进制数比如11.1。
小数部分 1 + 1 等于二,逢二进一,小数部分保留一个零。
小数点前的这一位,一加一,再加刚才进的一,等于3,3等于 2 + 1。逢 2 进1,我们需要再往更高位进1,这一位会留下一个1。
下一位1,加上刚才进的 1 就等于 2,逢 2 进1,这一位保留0,往高位再进1。
接下来最高位的计算 1 + 1 = 2,逢 2 进一,因此这一位保留0,再往高位进1。
因此这两个二进制数相加,得到的结果应该是 1001. 0。
这就是所谓的二进制, 逢二进一。如下:
(5)二进制
1.二进制优点
十进制是最符合我们人类习惯的一种计数方式。
而二进制是最适合用计算机来存储和处理的一种计数方式。
为啥呢?
①因为我们只需要使用有两个稳定状态的物理器件,就可以表示二进制的 0 和 1 了。比如之前介绍过的高电平、低电平,还有在电容当中,我们可以用电荷的正负性来表示 0 和1。
总之,我们可以很方便地使用一些物理器件来表示 0 和 1 这样的两种状态。
②另外一个原因, 0 和 1 可以刚好对应逻辑值的假和真。一般 0 表示假, 1 表示真。
这就可以很方便的用计算机来实现逻辑运算。
③第三个原因,我们可以很方便地使用逻辑门电路来实现算数运算。
跨考的同学可能不知道逻辑门电路是什么,这是一门叫做数字电路的课,里边会学习的内容。
无所谓,反正逻辑门电路也是用来处理二进制的一个元器件,你只需要知道这个就好了。
总之,这就是为什么现在的计算机世界会使用二进制的一个原因。
除了二进制之外,在计算机世界里我们还经常会使用到 8 进制和 16 进制。这两种计数方式和二进制能够比较好的进行一个对应。
所以如果要给人类阅读计算机里边存储的一些数据,我们把二进制转换成 8 进制或者 16 进制的表示方式会更方便一些。
2.二进制转换为r 进制
接下来我们来看二进制和 8 进制、 16 进制之间进行转换。
<1> 二进制转换为八进制
比如二进制数1111000010.01101
我们会发现八进制数它的奇基数 r 等于8,也就是每一个数码位总共有可能出现 8 种不一样的情况,而二进制数每一位只有可能出现 0 或 1 这样的两种情况。
如果我们把三个二进制位进行一个组合,这三个二进制位有可能出现的情况应该是 2 2 2 等于8,这就和八进制有可能出现的 8 种情况能够对应上了。
因此,如果我们要把二进制转成八进制,其实很简单,我们只需要三个二进制位为一组,每一组转换成对应的八进制符号就可以,也就是 0- 7。
对于上边给出的例子,我们每三个二进制数为一组。那么010这个二进制数表示的应该是2;000表示的是0;111表示的是7;最高位只剩一个1,由于我们要保证是三位一组,所以我们会在前边补上两个0凑组三位,所以 001 对应的是 1 。
小数部分也是一样的, 3 位为一组。如果不够,我们可能会需要补几个0,把它凑足 3 位。011 对应3, 010 对应的是2。
如下:
可能还是会有跨考的同学,不知道对应关系是怎么来的。
其实和之前是一样的原理,二进制数011,它的最低位的位权应该是1(2^0),第二位的位权应该是2(2^1),第三位的位权应该是4(2^2)。所以011这个二进制数转换成十进制应该是 11+12+0*4=3。因此 011 对应的就是3。
而111这个二进制数它所对应的实际数值应该是 11+12+1*4=7。
这是二进制到八进制的转换。
<2> 二进制转换为十六进制
比如二进制数1111000010.01101
二进制和十六进制的转换其实也是类似的,因为 4 个二进制数刚好可以表示出 16 种不一样的状态。因此每四位二进制为一组,每组转换成对应的十六进制符号就可以了。
对于刚才这个数,每4位为一组,把它转换成十六进制所对应的符号就可以了。如下:
我们重点来看一下 1100 的转换。
根据二进制数,这四位为一组,最低位的位权应该是1,其次是2、4、8。
所以 1100 它的实际数值应该是 8 + 4=12。
十六进制当中怎么表示12这个数呢? A是10, B是11, C是12,所以可以用 C这个字符来表示12。
因此, 1100 把它转换成对应的十六进制符号就是C。
对于小数部分也是类似的,只不过我们在最后有可能需要补上几个0,要凑足四位一组再进行转换。
整数部分补 0 是补在头部,小数部分补 0 是补在尾部。
3.r 进制转换为二进制
<1> 八进制
转换为二进制
比如八进制数 251.5
其实原理和之前是一样的,只不过是一个逆向的过程。
每一个八进制数最终应该可以转换成三位二进制。
这个例子中,2所对应的二进制应该是010,5所对应的二进制应该是101,1所对应的二进制应该是001,小数点之后还有一个5,对应的是101,所以这就是八进制数转换成二进制数的一个结果。
<2> 十六进制
转二进制
比如十六进制数 AE86.1
A表示的是 10 这个数值,我们用4位的二进制表示 10 应该是1010; E也是类似的,转换成二进制是1110。
这些对于跨考的同学来说,需要自己下去练习,这就不再赘述。
(6)进制常见书写方式
大家会注意到,刚才我们会用一个括号,然后写一个 8 的角标,表示这是一个八进制数
。
同样的方式,一个括号写一个 16 的角标,表示这是 16 进制数。
除了这种书写方式之外,我们还会遇到其他的书写方式。
比如二进制
的表示,我们会看到一串1010,最后加一个B,因为二进制是binary,所以结尾为 B 表示的是二进制。 十六进制
还会用 H 作为结尾,用这样的方式来表示。因为十六进制的英文是以 h 打头的。
我们还经常会见到 0X 后面跟一串数字,这个 0X 其实也是表示后面跟的这一串是一个十六进制的数。
而十进制
可以用 D 来表示,同样也是来自于它的英文。
因此,大家在做题的时候,如果题目没有特别说明这是什么进制,就需要观察它的一个书写的方式,特别是以字母结尾的书写方式。
三、真值和机器数
最后我们介绍两个简单的概念真值和机器数。
之前我们已经知道十进制数转换成二进制,二进制可以很方便地保存到计算机里,但是如果十进制数还带正负怎么办?
通常的解决方法是我们会增加一个标志位,符号位,用一个二进制的 0 或者 1 来表示正或者负。
在之后的学习中,我们会学到原码、反码、补码、移码。学习这些东西,大家就知道怎么在计算机里来表示带有正负的这种数了。
这就引出了两个概念真值和机器数。
所谓的真值
就是符合我们人类习惯的这种数字,而机器数
是指数字实际存到计算机里的一种形式。
我们需要把正负号进行一个数字化,把它变成对应的 0 或者1。
这就是所谓增值和机器数的概念,简单有个了解就可以。
四、回顾总结
这个小结内容比较多,我们介绍了进位计数制,这地方打错了,应该是制度的制。
我们介绍了所谓的 r 进制数是什么意思。
所谓 r 进制数就是每一个数码位有可能出现 r 种字符,逢 r 进1。
把 r 进制数转换成对应的十进制数的转换方法很简单,我们只需要用每一个数码位乘以这个数码位所在的位置的一个位权,相乘相加就可以。
对于程序员来说,我们需要熟练地掌握二进制到八进制或者十六进制的转换。
每 3 个二进制位对应 1 个八进制位,每 4 个二进制位对应 1 个 十六进制位。
如果题目让你把十六进制转换成八进制应该怎么办?你可以先把它转成二进制,再把二进制转成八进制,经过这样的一个中间步骤就可以了。
需要注意的是,我们需要补位,因为我们转换的过程中是三位一组或者四位一组,如果每一组凑不够这么多二进制数,我们就需要进行一个补位。对于整数部分,我们通常是在高位进行补位,而对于小数部分,我们通常是在低位进行补位。
十进制转换成 r 进制的转换方法,需要分为整数部分和小数部分来分别进行处理。整数部分的处理方法叫做除积取余法,每部分除以基数得到余数,然后先得到的余数应该是整数部分的低位。对于小数部分的处理,使用的是乘积取整法,先算得的数位应该是小数的高位,这一点一定需要注意。
除了课本上介绍的方法之外,如果大家能够熟练地写出各个位的位权,其实用拼凑的方法来进行转换也是很快的,当然取决于大家的个人习惯。
这个小节最后,我们还介绍了真值和机器数的概念,简单的了解一下即可。
另外还有一点需要强调的是,在用乘积取整法把小数部分转换成某进制的时候,有可能会遇到无法精确表示的情况,比如刚才我们举的 0. 3 那个例子。
而对于某些十进制数,比如 0. 5 或者0.725,对于这样的数,你只需要用乘积取整法乘上几次,你就会发现,小数部分变成了 0. 0,对于这样的数,就说明我们可以用二进制来精确地表示。这一点也是选择题当中的高频考点。
对于整数部分来说,我们肯定可以用二进制来精确表示,但是小数部分有可能无法精确表示。