搜索
写经验 领红包
 > 知识

补码的几个问题是什么(补码的几个问题怎么解决)

导语:补码的几个问题

补码是一个比较让人烦恼的问题。

1:补码的定义

图1

从上述定义可以看出,对于负数来说,

图2

这里的x代表的是一个负数,比如x=-101,n代表的是x这个负数不考虑符号位的数值的位数,在这里就等于3.图2可以变为

图3

这意味着,一个负数的补码加上这个负数的绝对值将出现归零的现象,比如

图4

这里1011是-5的补码,最高位是符号位,按照图3的定义,这里的n等于3,所以-5的补码

1011加上-5的绝对值5,即0101,得出的答案是2的4次方,也就是2^(n+1),而此时的结果已经超出了上面的数字的位数(包括符号位4位),如果保留四位,则结果是0000,也就是说,一个负数的补码加上这个负数的绝对值,会连同符号位一起归零。

当然,如果不算符号位,则就是3位数值部分相加

当然也会归零。

一个字节8位,如果采用原码表示正整数(含0),可以表达0-255,即 2^8=256,一共256种状态,从全0到全1的各种排列组合。如果要表示负数,则符号位需要占用一位(最高位,1代表负数,0代表正数),因此其绝对值最大范围为0-127,即2^7=128,一共正负各128种状态,如果不采用特殊处理,这时候0占用2个编码,10000000即负0,和00000000即正0,数据表示范围为-127到-0及+0到127,这样总体上一个字节只有255种状态,因为其中0具有正0和负0之分,这不符合数学意义也浪费一个编码。因此人们想到把负0利用起来,即当遇到负数时,采用补码来表示就可以解决这个问题,而遇到正数或0时还是保留原码表示。因此这个负0通过补码算法处理后自然而然地被利用起来,用来表示-128.

为了证明10000000这个负0代表-128补码的正确性,考虑

因为01111111是+127的原码,上述运算等于是计算了(-128+127)这个结果,很明显其结果应该是-1,而11111111正是-1的补码,其它可以类推,因此将10000000代表-128补码是正确的。

上述运算还表明,补码的重要功能就是把减法(127-128)运算变成了加法(-128+127)运算。

综上为:

补码:8位补码能够表示数的范围是 -128~127。

3:变形补码

对于小数来说,其补码定义为

图5

即小数补码的定义中,其整数部分的那一位是用来表示符号位的。

图6

图6的定义也是针对小数的,其中的100是二进制,表示数字4。这种定义就意味着每个小数有两个符号位。

图7

图8

图8为两个正小数相加,这种情况并没有发生溢出,这是因为这两个小数都小于0.5,所以它们的和小于1.如果是00.11+00.10,则结果为01.01,这种情况下就发生了溢出,因为两个小数的和已经超过了1.再比如

图9

这是两个负小数的补码相加,其结果也没有溢出。但如果仔细观察,可以看出,相加的过程中是发生了由小数的最高位向符号位的进位的,那为什么没有产生溢出呢?这是因为11.10101和11.10111这两个小数补码的数值部分都是大于0.5的,即意味着着两个负小数的绝对值是小于0.5的,而两个绝对值小于0.5的小数相加,其绝对值不可能大于1,而采用补码相加的话,其相加的绝对值却会超过1,因此会产生进位,但由于是两个负数相加,即

11.11 =-0.75

+ 11.10 =-0.5

-------------------------

111.01 =-1.25保留小数部分=-0.25

其最高位的那个1去掉,剩下11.01,即上面两个负小数的补码相加所产生的进位,被它们的符号位相加刚好抵消了。

本文内容由小里整理编辑!