在学习补码的时候有两个问题一直没有解决
1. 为什么按位取反一系列操作可以转换成正确的补码
2. 用补码比原码方便之处在哪里
1.按位取反操作获得补码
例如十进制数59 转换成 八位二进制数为 59-32 => 27-16 => 11-8 => 3-2 => 1
0011 1011
如果是-59则二进制码为 1011 1011
使用反码比使用原码第一个方便的地方在于可以把数值范围加一 ,8位二进制的范围是-127~127
补码的范围是-128~127
我们正常获得补码的操作是,符号位不变,其他有效位按位取反,然后把最后一位加上1得到,
那么补码的计算定义是【补】=M+【原】 其中溢出位直接舍弃掉。其中M=2^n
这里分为两种情况,第一种是正数的情况,例如59 的二进制原码 0011 1011
如果加上M 则为1 0011 1011最高位溢出舍去,所以正数的补码和原码相同,
那么按照简便操作,保留符号位0 其他位取反 0100 0100 末位加一 就是 0100 0101 显然,正数是不能这么取的,那么上边这几句话是废话....sorry
第二种情况是负数的情况 例如 -59 的二进制原码和补码计算是
1011 1011
1100 0101
可以看到,如果最后一位不加1,只进行按位取反操作,这两个数加起来一定是 1111 1111 那么这个数再加上一就是 1 0000 0000 也就是M
所以按照这种计算 得到的 -【原】+【补】=M 满足 补码计算定义,所以可以用这种方法对负数的补码进行计算。 ok
2.补码比原码方便的地方
所有相关的书籍中叙述都是原码在计算是需要考虑符号和实际的加减操作并进行相应的定义,但是补码不一样,他直接加起来就ok
这里分为三种情况,一是正+正,二是正+负,三是负+负
第一种
正数+正数肯定是和原码一样方便的,符号位是0,那就跟普通加法一样了。
第二种
正数+负数
如果是原码的话确实有很多不方便的地方,要考虑绝对值的大小还有最后的符号。
例如59 -26这个计算 如果是原码就要考虑双方的符号和绝对值大小,如果是补码计算的话
-26 是 1001 1010 补码就是 1110 0110
59 是 0011 1011
两者相加的补码为 1 0010 0001 最高位溢出是 33
负数+负数也是如此
即补码把加上负数的操作变成了加上一个正数,而这个正数是怎么来的呢,
相当于一个钟表如果需要把指针减少两个小时,也可以正向拨10个小时来解决,8位二进制数的相当于有128个刻度的大表盘,
补码等于反码+1,反码是由127减去原数,再加上一相当于用128减去原数,用这个数加上被减数就正好是减去之前的数了。