第三讲,我们来谈谈:“二进制的负数”

首先,你要记住并且不要问为什么:“在计算机中,所有的数据,最终都是使用二进制数表达的。

还要记住并且不要问为什么:“在计算机中,正数是直接用原码来表示和存储的。

要记住并且不要问为什么:“在计算机中,负数是以它的补码(即它的反码+1)来表示和存储的。

 

对于允许是负数的数值(称为带符号的数值),必须先确定一个固定的长度(换言之,就是二进制数的位数),再把最左边的最高位设置为符号位。必须固定位数,这样才能避免符号位与其他位的混淆。

只要知道每个数值的位数,就可以找到符号位,它应是最左边的那一位。如果符号位是0,该数值就是正的;如果它是1,该数值就是负的。

 

⑴原码表示法规定:套用十进制的思路,用最左边的最高位来表示该数的符号位(0表示正数,1表示负数),剩余的其他位数用来表示该数的绝对值。关键:理解符号位其他位数

原码:一个整数,按照其绝对值大小转换成二进制数,并在最左边的最高位用0或1来表示其正负,称为原码。

例①:正数 5 的原码是:0000 0101。

    而负数 -5 的原码是:1000 0101。

 

反码:将原码,除符号位外的其他位数每一位按位取反,所得到的新的二进制数,称为反码。(口诀:符号位不变其他位取反

⑵反码表示法规定:零、正数的反码与原码相同,负数的反码为对该数的原码除符号位外每一位取反。

例②:正数 5 的反码与原码相同:0000 0101。

    而负数 -5 的原码是:1000 0101,对该数的原码除符号位外每一位取反,得到反码:1111 1010。

 

补码:反码加1,称为补码。(口诀:符号位不变其他位先取反再加1

⑶补码表示法规定:零、正数的补码与原码相同,负数的补码为对该数的原码除符号位外每一位取反,然后在最后一位加1。

例③:正数 5 的补码与原码相同:0000 0101。

    而负数 -5 的原码是:1000 0101,对该数的原码除符号位外每一位取反,然后在最后一位加1,得到补码:1111 1011。

 

所以,在计算机中,负数 -5 是以它的补码(即它的反码+1):1111 1011 来表示和存储的。

 

不管是正数还是负数,其反码或补码的最高位,都是和原码的最高位一样!(请看原码表示法的规定,还有反码表示法和补码表示法的规定!)

  因为,正数的反码或补码,都是与原码相同,所以最高位是不变的。

  因为,负数的反码或补码,都是在原码的基础上,保持最高位不变,其他位数每一位取反,甚至在最后一位加1。

 

 

以上都是教我们,把我们熟悉的十进制的正数或负数,转化成计算机熟悉的二进制的数:

十进制:原码->符号位不变,先取反->反码->再加1->补码

那反过来,看到计算机熟悉的二进制的正数或负数,如何转换成我们熟悉的十进制的数?

补码->先减1->反码->符号位不变,再取反->原码:十进制

 

首先,要知道该二进制数的最高位:如果最左边的最高位(即符号位)为0则是正数,为1则是负数。

  二进制的正数,要转换成十进制,请先将其写成“加权系数展开式”,然后用“按位权相加”法,即可转换成十进制。

  二进制的负数,要转换成十进制,首先要理解上面的“在计算机中,负数是以它的补码(即它的反码+1)来表示和存储的”这句话的精髓,然后反过来逆推(符号位不变其他位先减1再取反):

 

例⑤:十进制的 -10 在原码表示法里,其原码是:1000 1010;对该数的原码除符号位外每一位取反,得到反码:1111 0101,然后在最后一位加1,得补码:1111 0110。

反过来逆推,二进制的 1111 0110(可理解为已知补码),先减1,得出(反码):1111 0101;除符号位外每一位取反,得出(原码):1000 1010;它在原码表示法里,最高位1表示负数,剩余的其他位数表示该数的绝对值,得:-10。

 

再看看逆推过程:

1111 0110

先     -1

---------

1111 0101

再取反:

---------

1000 1010 = 在原码表示法里,最高位1表示负数,剩余的其他位数表示该数的绝对值,得:-10。

(这是按照补码的原理来逆推原码。相当于只有0点和6点的钟,原来在0点,逆时针拨可到6点)

 

试试对该二进制数求补码:

1111 0110

先取反:

---------

1000 1001

再     +1

---------

1000 1010 = 用原码表示法来理解,也是十进制中的 -10。

原码取反加1得补码补码取反加1也得出原码。这是抖机灵。相当于只有0点和6点的钟,原来在0点,顺时针拨也可到6点)

 

如果已知补码求原码,可将补码过程逆推(即符号位不变,其他位先减1再取反)即得到原码,亦可将该补码再求补码(即符号位不变,其他位先取反再加1)也能得到原码

  其实,看到某个二进制数,你可以理解为已经知道补码,只需用上面定律⑸求出原码,最后将原码转换成十进制,不就行了?

 

一个二进制数,如果每位取反(最高位符号位也取反,所以不是反码),取反得到的值和原来的值,相加等于-1(不是0,也不是1)

  所以,求某个二进制数取反的值,可用:-1-(该二进制数的值),即该二进制数的值的相反数减1。

 

 

 

 

 

 

原码、反码、补码的使用

计算机中有三种编码方式表示一个数。

正数的三种编码都是相同的。如:

+1 = 0000 0001 [原码] = 0000 0001 [反码] = 0000 0001 [补码]

负数的三种编码都是不同的。如:

-1 = 1000 0001 [原码] = 1111 1110 [反码] = 1111 1111 [补码]

只有原码才是可以直接被识别并且用于计算方式 ,那么反码和补码的作用又是什么?

人脑在进行计算的时候可以知道第一位是符号位,在计算的时候会根据符号位选择对真值的加减。

对于计算机来说,加减乘除是最基础的运算,要尽量设计的简单,计算机辨别出 符号位 会使得计算机的基础电路设计变得更加复杂,所以人们想出了将符号位也参与运算的方法。

减去一个正数等于加上一个负数,即 2-1 = 2+(-1),所以机器只有加法而没有减法。符号位参与运算,只保留加法运算。

(一)原码运算:

十进制的运算:1-1=0

1-1=1+(-1) = 0000 0001 [原码] + 1000 0001 [原码] = 1000 0010 [原码] = -2

如果用原码表示,让符号位也参与计算,对于减法来说,结果显然是不正确的,所以计算机内部不使用原码来表示一个数字。

 

(二)反码运算:

为了解决原码做减法的问题,就引出了反码

十进制的运算:1-1=0

1-1=1+(-1) = 0000 0001 [原码] + 1000 0001 [原码] = 0000 0001 [反码] + 1111 1110 [反码] = 1111 1111 [反码] = 1000 0000 [原码] = -0

使用反码计算减法,结果的真值部分是正确的,但是在 ‘0’这个特殊的数值上。虽然 +0和 -0在意义上是一样的,但是0加上符号是没有任何意义的,0000 0000[原码] 和1000 0000[原码] 这两个编码都表示0。

 

(三)补码运算:

补码的出现,解决了 0 的符号以及两个编码的问题。

十进制的运算:1-1 =0

1-1=1+(-1) = 0000 0001 [原码] + 1000 0001 [原码] = 0000 0001 [补码] +  1111 1111[补码] = 0000 0000[补码] = 0000 0000[原码] = 0

这样 0 用 [0000 0000] 表示 ,而以前出现问题的 -0 就不存在了,而且可以用 [1000 0000] 表示 -128

(-1) + (-127) = 1000 0001[原码] + 1111 1111[原码] = 1111 1111[补码] + 1000 0001[补码] = 1000 0000[补码] = -128

-1-127 的结果应该是 -128,在用补码运算的结果中,1000 0000[补码] 就是-128,但是注意因为实际上使用 -0 的原码来表示 -128,所以 -128并没有补码和反码表示。

使用补码,不仅是修复了 0的符号以及存在两个编码问题,而且还能多表示一个最低数。

注意:

1、所以8 位的二进制,使用原码或是反码表示的范围为 [-127,+127],使用补码表示的范围为 [-128,127];

2、常用的32 位二进制,使用补码表示的范围为  [-231, 231-1] ,这是因为第一位表示的是符号位,使用补码表示时又可以多保存一个最小值。

 

五、原码、反码、补码算术运算

(一)反码的算术运算

反码的运算注意问题:

1、反码运算时,符号位与数值一起参与运算;

2、反码的符号位相加后,如果有进位产生,就要·把进位送回到最低位相加(循环进位);

3、用反码运算,其运算结果也为反码。在转换为真值时,若符号位为0,数位不变;若符号位为1,应将结果求反才是其真值。

[例1] 已知X = + 1101 , Y = + 0110 , 用反码计算Z = X-Y。

解: [X]反 = 01101,[-Y]反 = 11001,则[Z]反 =[X]反+[-Y]反 = 01101+11001+1(循环进位)= 00111 , 其真值为Z = +0111。

[例2] 已知X = + 0110 , Y = + 1101 , 用反码计算Z = X-Y。

解: [X]反 = 00110,[-Y]反 = 10010,则[Z]反 =[X]反+[-Y]反 = 00110 + 10010= 11000 , 其真值为Z = - 0111。

采取反码运算较好的解决了原码运算所遇到的困难或问题,但由于循环进位需要二次算术相加,延长了计算时间,这同样给电路带来麻烦。

而采用下述的补码运算则可避免循环进位的两次计算,同时,采用补码运算对溢出的判断也较采用反码简单的多,所以机器中的算术运算普遍采用补码运算

 

(二)补码的算术运算

补码要注意的问题:

1、补码运算时,其符号位与数值部分一起参加运算

2、补码的符号相加后,如果有进位的出现,需要将这个进位舍去(自然丢失)

3、用补码运算,其运算结果也是补码。在转换为真值时,若符号位为 0,数位不变;若符号位为1,应将结果求补才是其真值。

[例3] 已知X = + 1101 , Y = + 0110 , 用补码计算Z = X-Y。

解: [X]补 = 01101,[-Y]补 = 11010,则[Z]补 =[X]补+[-Y]补 = 01101+11010= 100111 , 其真值为Z = + 0111。

[例4] 已知X = + 0110 , Y = + 1101 , 用补码计算Z = X-Y。

解: [X]补 = 00110,[-Y]补 = 10011,则[Z]补 =[X]补+[-Y]补 = 00110 + 10011= 11001 , 其真值为Z = - 0111。

 

(三)溢出及补码溢出的判断

无论采取什么机器,只要运算的结果大于数值设备所能表示数的范围,就会产生溢出。溢出现象应该当成是一种故障来处理,因为它使结果数产生错误。

异号两数相加时,实际是两数的绝对值相减,不可能产生溢出,但有可能出现正常进位;

同号两数相加时,实际上是两数的绝对值相加,既可能产生溢出,也可能出现正常进位。

[例5] 某数字设备用五位二进制表示数,计算

(1)9+3 (2)-9-3 (3)9+12 (4)-9-12

解:(1)[+9]补+[+3]补= 01001+ 00011 = 01100 = +12 正确;

(2)[-9]补+[-3]补= 10111+ 11101 = 110100 = 10100(符号位进位自然丢失),其真值为-1100 = -12正确;

(3)[+9]补+[12]补= 01001 + 01100 = 10101 其真值为-1011 =-11错误,产生了溢出;

(4)[-9]补+[-12]补 = 10111+10100 = 101011 其真值为01011= +11 错误,产生了溢出。

(1)、(2)两题结果均正确,查其最高位和次高位的进位位,不是均无进位产生,就是均产生进位;(3)、(4)两题结果均错误,查其最高位和次高位的进位位,只有一位产生了进位。此即为判断机器是正常进位还是溢出的基本依据,在微型机中可用异或电路来实现上述的判断。

 

reference

https://www.cnblogs.com/zhangziqiu/archive/2011/03/30/ComputerCode.html

https://www.cnblogs.com/nyw1983/p/11887220.html

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值