期末总结系列1——数的表示

计组期末总结系列1——数的表示

 

————————下面是一些开头的废话,可以不看————————

由于电脑坏了,又不能整天玩手机,舍友说计组不会,为了方便同学复习,同时总结一下整个学期学习的内容,所以决定写写一些重点的内容(虽然导论、C语言、电路都讲过三遍了,然而还是可以有人不会啊╮(╯▽╰)╭)。另,本人水平有限,如果文中有错误还请批评指正。

——————我是分割线,上面的废话可以不看,下面才是重点————————

在计算机中,所有的数字都是用二进制来表示的,为了理解记忆而不去记忆大量的公式,不得不从头好好思考二进制。

我们都知道在十进制中,以一个数字为例:1234.4321,想想这个数字的含义,如果什么都不说,我们都会默认这是一个十进制的数字。1234.4321 = 1234 +0.4321,可以分成两个部分来表示,也就是整数部分和小数部分。我们分别来看这两个部分。

1234     = 1 * 1000 + 2 * 100 + 3 * 10 + 4 * 1

= 1 * 10^3 + 2 * 10^2 + 3 * 10^1 + 4 * 10^0

每一位代表着不同的意义,从右往左看

第0位的数字代表了有多少个1,也就是10^0

第1位的数字代表了有多少个10,也就是10^1

第2位的数字代表了有多少个100,也就是10^2

第3位的数字代表了有多少个1000,也就是10^3

以此类推

0.4321 = 4 * 0.1 + 3 * 0.01 + 2 * 0.001 + 1 * 0.0001

= 4 * 10^-1 + 3 * 10^-2 + 2 * 10^-3 + 1 * 10^-4

小数点后的部分,从左往右看

第0位的数字代表了有多少个0.1,也就是10^-1

第1位的数字代表了有多少个0.01,也就是10^-2

第2位的数字代表了有多少个0.001,也就是10^-3

第3位的数字代表了有多少个0.0001,也就是10^-4

上面所说的十进制代表了每位数字的权值都是10的幂次。

同理类推到二进制。

 

以1010.1001为例

1010.1001 = 1010 + 0.1001

整数部分,从右往左看

1010      = 1 * 8 + 0 * 4 + 1 * 2 + 0 * 1

= 1 * 2^3 + 0 * 2^2 + 1 * 2^1 + 0 * 2^0

 

第0位的数字代表了有多少个1,也就是2^0

第1位的数字代表了有多少个2,也就是2^1

第2位的数字代表了有多少个4,也就是2^2

第3位的数字代表了有多少个8,也就是2^3

 

小数点后的部分,从左往右看

0.1001 = 0.1 + 0.00 + 0.000 + 0.0001

=1 * 2^-1 + 0 * 2^-2 + 0 * 2^-3 + 1 * 2^-4

第0位的数字代表了有多少个0.5,也就是2^-1

第1位的数字代表了有多少个0.25,也就是2^-2

第2位的数字代表了有多少个0.125,也就是2^-3

第3位的数字代表了有多少个0.0625,也就是2^-4

八进制和十六进制同理。

 

进制之间的转换:

十进制  二进制  八进制  十六进制

如果你理解了上面所述的含义,那么转换也会非常容易理解。不同进制数字的含义最终都是为了表示数字,换句话说也就是一个数字可以以不同的方式表示出来。

 

十进制转二进制方法

以1234.4321为例进行说明。

整数部分的转换:

由于二进制每位的权值都是2的幂次,所以为了方便转化可以先写出几个算好的2幂次结果

2^10 2^9 2^8 2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0
1024 512 256 128 64 32 16 8 4 2 1

 

寻找小于1234且尽可能大的数或者等于1234的位写1,如下表

 

2^10 2^9 2^8 2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0
1024 512 256 128 64 32 16 8 4 2 1
1

用1234 – 1024 = 210

寻找小于210且尽可能大的数或者等于210的位继续写1,如下表

 

2^10 2^9 2^8 2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0
1024 512 256 128 64 32 16 8 4 2 1
1 1

 

用210 – 128 = 82

寻找小于82且尽可能大的数或者等于82的位继续写1,如下表

 

2^10 2^9 2^8 2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0
1024 512 256 128 64 32 16 8 4 2 1
1 1 1

 

用82 – 64 = 18

寻找小于18且尽可能大的数或者等于18的位继续写1,如下表

 

2^10 2^9 2^8 2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0
1024 512 256 128 64 32 16 8 4 2 1
1 1 1 1

 

用18 – 16 = 2

寻找小于2且尽可能大的数或者等于2的位继续写1,如下表

 

2^10 2^9 2^8 2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0
1024 512 256 128 64 32 16 8 4 2 1
1 1 1 1 1

 

最后,剩余位写0,结果就是转换成二进制的整数部分。

 

2^10 2^9 2^8 2^7 2^6 2^5 2^4 2^3 2^2 2^1 2^0
1024 512 256 128 64 32 16 8 4 2 1
1 0 0 1 1 0 1 0 0 1 0

 

结果为 10011010010

 

小数部分0.4321,进行乘二取整。

0.4321 * 2 = 0.8642  整数部分为0

0.8642 * 2 = 1.7284  整数部分为1

0.7284 * 2 = 1.4568  整数部分为1

0.4568 * 2 = 0.9136  整数部分为0

0.9136 * 2 = 1.8272  整数部分为1

以此类推直到小数部分为零,把上面取到的整数部分从左到右排列即是二进制小数0.01101,注意,需要几位就算几次。

 

其他的转换:

二进制,八进制,十六进制之间都可以方便的进行转换,因为每三位二进制数字相当于八进制的一位数字,每四位相当于十六进制的一位数字。

 

定点整数的表示

首先,在计算机中所有的数字都是二进制储存的,但是,为了方便书写和节省位数一般用十六进制来表示,两位就能表示八位的二进制数字。

编码有三种,原码,反码,补码。接下来详细说明。为了方便观察,我们在能观察规律的情况下尽可能缩短长度来说明。

由于有正数和负数,所以需要一位标识位来区分是正数还是负数。先说原码,取字长位三位,其中第一位是符号位,0代表正1代表负,那么它可以表示的数字是这样的、

原码 真值
0 0 0 0 0
1 0 0 1 1
2 0 1 0 2
3 0 1 1 3
4 1 0 0 -0
5 1 0 1 -1
6 1 1 0 -2
7 1 1 1 -3

 

jz1-1

表中第一列是单纯作为二进制来看这三位数的十进制数字。原码的特点非常容易看出来,有两个0,一个是100一个是000,都是代表了0,表达的范围是对称的。计算方法也很好理解,由于只有2位可以用来表示数本身,所以可以表示的数范围就是0 ~(2^2)-1也就是0~3,算上负数的那部分也就是-3~+3,推广一下很容易得到范围的公式,-((2^n)-1)~+(2^n)-1,也就是1-2^n~2^n-1,其中的n是不算符号位在内的位数。

最大的正数是011,也就是3,

最小的正数是001,也就是1

最大的负数(绝对值最小的负数)是101,也就是-1

最小的负数(绝对值最大的负数)是111,也就是-3

 

接下来是反码,需要注意的是,正数的反码和原码一样,正数的反码和原码一样,正数的反码和原码一样,负数的反码就是把原码按位取反得到的,符号位不变。符号位不变。符号位不变。(重要的事情说三遍)效果如下表

反码 真值
0 0 0 0 0
1 0 0 1 1
2 0 1 0 2
3 0 1 1 3
7 1 1 1 -0
6 1 1 0 -1
5 1 0 1 -2
4 1 0 0 -3

 

jz1-2

显然,范围没变,但是对应关系有了一些变化,和原码表示相同的是,0依然有可以有2个编码来表示。

最后是补码,正数的补码和原码一样。正数的补码和原码一样。正数的补码和原码一样。负数的补码是在它的反码基础上再加1,这个加1的运算符号位要参与运算。这个加1的运算符号位要参与运算。这个加1的运算符号位要参与运算。效果如下。

补码 真值
0 0 0 0 0
1 0 0 1 1
2 0 1 0 2
3 0 1 1 3
0 0 0 0 0
7 1 1 1 -1
6 1 1 0 -2
5 1 0 1 -3

结果会发现还有一个编码空着,就是100,所以规定用100表示-4,如下表

补码 真值
0 0 0 0 0
1 0 0 1 1
2 0 1 0 2
3 0 1 1 3
0 0 0 0 0
7 1 1 1 -1
6 1 1 0 -2
5 1 0 1 -3
4 1 0 0 -4

jz1-3

这样既可以多表示一个数字,扩大了表示范围,还统一了0的编码。并且用补码表示还有一个特点,仔细观察上面的表格,如果用111+001,结果将会是000,高位会直接溢出而消失。正好和-1+1 = 0吻合。所以计算机中都用二进制补码来表示数字。补码能表示的范围显然是-(2^2)~2^2-1,推广下就是-(2^n)~2^n-1,其中的n依然不包括符号位在内。

最大的正数是011,也就是3,

最小的正数是001,也就是1,

最大的负数(绝对值最小的负数)是111,也就是-1,到此为止和原码一样

最小的负数(绝对值最大的负数)是100,也就是-4,

注意:这个数字很特殊,真值不能直接求原码来算。可以由以下两种思路来理解。

第一种:按照原码中最小的负数再减1来计算。比如

三位的编码最小的负数用原码表示为111,是-3,那么这个数就代表的是-4

四位编码中最小的负数用原码表示为1111,是-7,那么1000就代表-8

第二种:按照一对儿相反数相加为0来考虑。

寻找一个和100相加为000的数,那么是一定是100,把这个100当成二进制编码来换成十进制,也就是4,那么补码100代表的就是-4

简化过程就可以直接把补码100当成二进制转换,结果再取反即可得到补码100的真值。

再比如补码1000,转成十进制就是8,那么它表示的真值就是8的相反数-8

 

注意总结上面的规律(前提条件是以补码表示

最大的正数:

符号位一定是0,由于要求是最大,所以剩下的位数都是1即可,以8位编码为例,最大的正数就是0111 1111。可以按权值展开计算真值,但是这里有个小技巧,可以先把这个数加1,结果是1000 0000,然后转换,结果是2^7 = 128,之后再减1,也就是127。所以考试如果出现n位的话可以直接写出结果,也就是2^(n-1)-1。

最小的正数就不用说了,一定是1。

最大的负数(绝对值最小的负数):

有几位就写几位1,以8位编码举例,就写8个1,也就是 1111 1111,真值以上面第二种思路来理解非常方便,结果是-1.

最小的负数(绝对值最大的负数):

符号位一定是1,剩下几位写几个0。以8位编码为例,就写1000 0000,真值类比上面的思路来求,结果是-128。

这几个数在数轴上的位置如下图

jz1-4

接下来说说定点小数的表示。

在十进制中,表示的方法都很熟悉了,但是一定要仔细思考含义,才能理解二进制中定点小数的表示。

十进制中:把1个1分成10份,其中的一份就表示为0.1,如果分成100份,其中的一份就是0.01,如果分成1000份,其中的一份就是0.001

二进制中同理,把1个1分成2份,其中的一份就表示为0.1,如果分成4份,其中的一份就是0.01,如果分成8份,其中的一份就是0.001

注意虽然写出来一样,但是含义完全变了。

由于是小数,所以整数部分是0,延续定点整数的思路,把这位数当做符号标识,称为符号位。类比前面整数部分,依然可以有如下的三种表示方法,按顺序分别是原码,反码,补码。依然以3位编码为例。

原码 真值
0 0 0 0 0.00 0.00
1 0 0 1 0.25 2^-2
2 0 1 0 0.50 2^-1
3 0 1 1 0.75 (2^-1)+(2^-2)
4 1 0 0 -0.00 -0.00
5 1 0 1 -0.25 -2^-2
6 1 1 0 -0.50 -2^-1
7 1 1 1 -0.75 -((2^-1)+(2^-2))

最大的正数是011,也就是0.75,

最小的正数是001,也就是0.25,

最大的负数(绝对值最小的负数)是101,也就是-0.25,

最小的负数(绝对值最大的负数)是111,也就是-0.75,

反码 真值
0 0 0 0 0.00 0.00
1 0 0 1 0.25 2^-2
2 0 1 0 0.50 2^-1
3 0 1 1 0.75 (2^-1)+(2^-2)
7 1 1 1 -0.00 -0.00
6 1 1 0 -0.25 -2^-2
5 1 0 1 -0.50 -2^-1
4 1 0 0 -0.75 -((2^-1)+(2^-2))

 

补码 真值
0 0 0 0 0.00 0.00
1 0 0 1 0.25 2^-2
2 0 1 0 0.50 2^-1
3 0 1 1 0.75 (2^-1)+(2^-2)
0 0 0 0 -0.00 -0.00
7 1 1 1 -0.25 -2^-2
6 1 1 0 -0.50 -2^-1
5 1 0 1 -0.75 -((2^-1)+(2^-2))

同理,补码空余出了一个编码就是100,所以规定用100来表示-1、用100来表示-1、用100来表示-1

补码 真值
0 0 0 0 0.00 0.00
1 0 0 1 0.25 2^-2
2 0 1 0 0.50 2^-1
3 0 1 1 0.75 (2^-1)+(2^-2)
0 0 0 0 -0.00 -0.00
7 1 1 1 -0.25 -2^-2
6 1 1 0 -0.50 -2^-1
5 1 0 1 -0.75 -((2^-1)+(2^-2))
4 1 0 0 -1

 

最大的正数是011,也就是0.75,

最小的正数是001,也就是0.25,

最大的负数(绝对值最小的负数)是111,也就是-0.25,到此为止和原码一样

最小的负数(绝对值最大的负数)是100,也就是-1,

注意:这个数字很特殊,真值不能直接求原码来算。

 

注意总结上面的规律(前提条件是以补码表示

最大的正数:

符号位一定是0,由于要求是最大,所以剩下的位数都是1即可,以8位编码为例,最大的正数就是0111 1111。可以按权值展开计算真值,但是这里有个小技巧,可以先把这个数加0000 0001,结果是1000 0000,然后转换,结果是1,之后再减0000 0001,也就是1-2^-7。所以考试如果出现n位的话可以直接写出结果,也就是1-2^-n。其中的n不算符号位

最小的正数:

符号位一定是0,由于要求最小,所以把权值最小的最低位直接写1,以8位编码为例,结果是0000 0001,表示2^-7

最大的负数(绝对值最小的负数):

符号位一定是1,剩下几位写几个1。以8位编码为例,就写1111 1111,真值类比上面的思路来求,结果是-(1-2^-7)。

最小的负数(绝对值最大的负数):

符号位一定是1,剩下几位就写几个0,以8位编码为例,就是1000 0000,那么它一定是-1。

 

画张图更好理解这四个数字的位置。

jz1-5

最后是浮点数。

把定点整数和定点小数结合起来表示,就是浮点数。它的原理类似于科学计数法,比如1.5*10^50,那么只需要把1.5和50记下来,就能描述一个非常大的数字,同理也可以描述非常小的数字,指数部分就相当于记录了小数点的位置。所以仿照这个方法,也可以把一个数表示成0.8*2^30的形式,再记录下0.8和30两个部分来表示这个很大的数字,这就是浮点数的表示法。前面的部分称之为尾码,指数部分称之为阶码。尾码部分用上面的定点小数来表示,指数部分用定点整数来表示。阶码在前尾码在后,组合后的编码就是浮点数的编码。

浮点数的表示范围由于受尾码影响,所以和定点小数范围类似,但是又因为阶码的存在扩大了范围,所以在非常接近0的部分是无法表示的。可以看出,尾码的正负决定了整个浮点数的正负,阶码的大小决定了与0的距离。仔细思考这句话,你就能准确的找到浮点数的表示范围。要时刻记得阶码当成定点整数尾码当成定点小数

jz1-6

下面以8位浮点数编码为例,规定前4位为阶码,1位符号位,后4位为尾码,1位符号位。均以补码表示

 

最大的正数:

 

要求阶码是最大的正数,

同时尾码也是最大的正数。

结果是0111 0111,

前4位当成定点整数求真值,为2^3-1 = 7

后4位当成定点小数求真值,为1-2^-3 = 0.875(注:如果幂次太高可以不算结果),

所以最终表示的真值是0.875*2^7

 

 

 

最小的正数:

 

要求阶码为最小的负数(绝对值最大负数),

同时尾码为最小的正数。

结果是1000 0001,

前4位当成定点整数求真值,为-2^3 = -8

后4位当成定点小数求真值,为2^-3 = 0.125,

所以最终表示的真值是0.125*2^-8

 

 

 

最大的负数(绝对值最小的负数):

 

要求阶码为最小的负数(绝对值最大负数),

同时尾码为最大的负数(绝对值最小负数)。

结果是1000 1111,

前4位当成定点整数求真值,为-2^3 = -8

后4位当成定点小数求真值,为-2^-3 =-0.125,

所以最终表示的真值是-0.125*2^-8

 

 

 

最小的负数(绝对值最大的负数):

 

要求阶码为最大的正数,

同时尾码为最小的负数(绝对值最大负数)。

结果是0111 1000,

前4位当成定点整数求真值,为2^3-1 = 7

后4位当成定点小数求真值,为-1,所以最终表示的真值是-1*2^7

 

综上所述,浮点数的范围为-1*2^7~-0.125*2^-8  0.125*2^-8~0.875*2^7

 

但是为了提高运算精度,所以做了规格化(证明略),受影响的就是接近0左右两边的两个分界点。规格化后变化如下

最大负数(绝对值最小负数)变为1000 1011尾码变成了-((2^-1)-(2^-3)) = -0.375,结果是-0.375*2^-8

最小正数变为1000 0100 尾码变成了2^-1 = 0.5,结果是0.5*2^-8

所以规格后的范围是-1*2^7~-0.375*2^-8  0.5*2^-8~0.875*2^7

 

0 Comments
Leave a Reply