数制
本来已经写好了很久了,没想到恢复智障了,搞到现在。这里也记录一下我当时的感受吧。一个大早上就这么废掉了。也就是花了一个早上和一个晚上的时间才整理出这些鬼东西。
关于数值,这里不进行记录什么二进制、十进制之类的基本概念,只介绍一些主要的知识点。
1、数制之间的转换
(1)关于二进制的一些概念
这里主要记录一下位、比特对于二进制的描述。这些东西描述起来也很麻烦,可能是我还没有掌握吧。
位宽/比特:一个二进制数,有它的位宽,有多少个0/1,它位宽就是多少;比如二进制数10110,它的位宽就是5,从第0位到第5位;也说这是一个5位宽的二进制数,这是个二进制数大小是5比特。
最高位和最低位:对于上面的10110,最高位是1,最低位是0;最高位是第4位,最低位是0
(2)二进制转换成十进制:
①二进制转换成十进制方法为:把二进制数按权展开、相加即得十进制数。
②举例:二进制数10011.01,位数为1的有第4位,第1位,第0位,第-2位,那么就有:
10011的十进制数值(注意说到数值,默认是转换为十进制时数的大小)为:2^4 + 2^1 + 2^0 + 2^(-2) = 19.25
十进制转换成二进制:
①转换方法就是:整数部分,除二取余;小数部分,乘二取整(小数部分一般会说明要精确到小数点多少位)。
②举例说明:将35.63转换成二进制数,小数部分精确到小数点后3位
那么对于整数部分,除二取余
整数部分的二进制数就是100011。
对于小数部分:乘二取整
0.63*2 = 1.26,取1;0.26*2 = 0.52,取0;0.52*2 = 1.04,取1;已经达到三位了。因此小数部分就是101
因此35.63的二进制表示为100011.101。
(3)二进制转换成八进制:
①方法:从小数点向两边展开,每三位二进制划分为一组,每一组的的十进制就是对应的八进制,(注意,最高位或者最低位不够3位要补0)。
②举例:1001.01转换成八进制,进行分组 (00)1 001 . 01(0),转换成八进制就是11.2。
八进制转换成二进制:
①八进制转换成二进制的方法跟二进制转换成八进制的方法相反,一位八进制对应三位的二进制,依次展开就可以。
②举例:八进制67.21转换成二进制,6是110,7是111,2是010,1是001;所以对应的二进制就是110111.010001。
(4)二进制转换成十六进制,十六进制转换成二进制:
二进制转换成十六进制/十六进制转换成二进制与八进制的类似,只不过是八进制对应的是3位,而十六进制对应的是4位;这里不再详述。
它们之间的转换都可以通过二进制进行。
2、二进制的有符号与无符号
(1)无符号数,也就是没有正负之分,默认为正值,上面说到的都是正数,也就是无符号数。对于二进制也是这样。
·一般情况下,没有专门支持这个数是有符号的,就默认是无符号的数。
·n位无符号可以表示的范围位0~+(2^n-1),即0~1...1
(2)有符号数,顾名思义就是有正负之分,比如+39,-49。对于二进制数而言,也有有符号数之分。以后我记录的说到有符号数的,默认指有符号数的二进制数。
①在有符号的二进制数中,最高位表示符号位,其他位表示数的其他内容;其中符号位是1时,表示这个有符号的二进制数是负数;符号位是0时,表示这个有符号的二进制数是正数。
比如有符号数10010,最高位是1,表示这个二进制数是负数。(当然要注意下面要讲到的反码)
·从前面上述可以知道,一个有符号的二进制数,至少有两位,其中一位是符号位。
②有符号二进制数有三种表达方式:原码、反码、补码(十进制之类的也有补码之类的,这里仅仅记录与二进制有关的)。
③原码:最高位是符号位,除最高位后的二进制数,表示二进制数值的绝对值大小。
比如原码100110,最高位是1,表示负数;剩余是00110,表示的数值大小是6,那么这个原码表示的数值大小就是-6 。
·一般情况下,说到是有符号数,一般指的是原码。
·原码的0,可以表示为+0和-0,也就是1...0,0..0,因此有两种表达形式。
·n位原码表示的范围为:-(2^(n-1)-1)~+(2^(n-1)-1),即1...1~0...1
④反码:反码可以由原码出发得来,将原码的每一位都取反就得了对应的反码。
比如一个有符号数的原码是10011,那么这个有符号数的反码就是01100.
·反码在应用不多,也许是我还没有了解到吧,在此不详述,以后用到了再详述记录吧。
⑤补码:补码的应用就广泛了,计算机的内部运算就是用补码的。
补码也可以由原码得来:
对于正数:补码即为补码;
对于负数:原码的符号位不变,剩余位取反,然后整体加一就得到了补码。
比如:二进制的原码是10010,符号位1不变;剩余0010,取反得1101;整合为11101,加一得到11110.也就是原码是10010的补码为11110 。
·补码的0,假设有4位,那么对于-0,原码是1000,进行取反加一后,得到0000(假设位宽固定);对于+0,补码也是0000;因此补码的0只有一种表达形式。
·n位补码表示的数值范围为:-2^(n-1)~+(2^(n-1)-1)
3、二进制的加减运算与溢出现象
(1)二进制的加减运算
①对于一般的无符号运算,直接运算就好了,没什么可以说的。但是计算机内部,它是用补码运算的,这就就有可以记录的地方了,补码的加减运算对于其他的有符号数,就显得比较简单了。此外,减法也可以当成加法来,减一个数可以当成加这个数的负数。
②对于补码的加法运算有:补码 + 补码 = 补码。当然这个是有一定的条件的,下面举例探讨。
③例一:(+3) + (+4),结果显然是+7;用二进制补码进行运算,则是0011+0100,得到的结果是0111,很显然,0111是+7的补码。
例二:(-2) -6 = (-2)+ (-6),结果显然是-8;用二进制补码进行运算,则是1110 + 1010 ,得到11000,这个很显然也是-8的补码。
例三:+6 - 3 = (+6)+ (-3),结果显然是+3;用二进制补码进行运算,则是0110+1101,结果是10011,诶呀,这个很显然就不是+3的补码,但是,当我们去掉最高位后,只看低四位0011,这个很显然是+3的补码呀。
例四:+4-7 = (+4)+(-7),结果是显然是-3;用二进制补码进行运算,则是0100+1001,得到的结果是1101,这个结果很显然是-3的补码。
(2)溢出现象
①经过上面的四个例子,引入溢出这个概念:如果加法操作产生的几个超出了数制定义的范围,就说发生了溢出。两个异号数相加,肯定不会溢出;同号相加可能溢出。
②判断溢出的法则:如果加数的符号相同,而和的符号与加数符号不同,则有加法溢出。
③再谈前面的四个例子:
一般而言,对于位宽固定的情况下,
例一相加,得到的是4位,没有溢出,结果也正确。
例二,虽然得到的结果正确,但是得到的结果是5位的,如果截去最高位,那么得到结果将是错误的,也就是有溢出产生。这里也提醒我们,对于同号相加,要加多一位,其实也就是加多一个符号位。
例三结果虽然是不正确的,但是这是5位的结果,我们截去最高位,这个结果是对的,因此这个没有溢出,也就是这个结果(四位)还是对的。
例四,没有溢出。