补码、补码非快速计算
补码高有效位大部分是1
以补码为1101为例:
1 | 1 | 0 | 1 |
所以补码1101的十进制数值为-8+4+1 = -3。
拓展补码的位表示:
如果要将补码拓展转换为更大的数据类型,那么就在新增的高有效位中填充,原始最高有效位的值。推导如下:
先拓展1位:
1 | 1 | 1 | 0 | 1 |
原来第4位的权值为-8,现在拓展后的第4位和第5位的权值和为-16+8 = -8,就相当于没拓展一样。所以很明显补码1 1101的数值还是为-3。
直接拓展4位:
1 | 1 | 1 | 1 | 1 | 1 | 0 | 1 |
原来第4位的权值为-8,现在拓展后的第4位到第8位的权值和为-128+64+32+16+8 = -8,就相当于没拓展一样。所以很明显补码1111 1101的数值还是为-3。
缩减补码的位表示:
反向思考,既然可以拓展位表示,那么其实也可以缩减位表示。
减小1位:
1 | 0 | 1 |
现在计算权值-4+1 = -3。发现缩减位表示后,十进制数值还是不变的。但是这种缩减是有前提的:从第一个1开始,到遇到的第一个0之前的1结束,也就是说,第一个0之前在缩减之后,必须至少有一个1。
补码1111的数值是-1,按照上面的定义,因为没有0,那么可以缩减到补码1,其数值也是-1。
1 | 1 | 1 | 1 |
-8+4+2+1=-1
1 |
-1 = -1
例题:
计算补码0xfffffffa的十进制数值。
因为0xf是1111,所以直接缩减这个补码的位表示,0xa是1010,那么实际上这个补码的位表示可以简化为1010,即-8+2=-6。
计算补码非:取反加1
本章以及下一章内容来自《深入理解计算机系统》练习题2.33后的网络旁注:补码非的位级表示
问题:给定一个数x的补码位表示,请给出-x的补码位表示。
原理:-x的补码位表示,即为x的补码位表示的每位取反再加1,最后再按照最低4位有效位截断。
示例表格:
[0101] 5 | [1010] -6 | [1011] -5 |
[0111] 7 | [1000] -8 | [1001] -7 |
[1100] -4 | [0011] 3 | [0100] 4 |
[0000] 0 | [1111] -1 | [0000] 0 |
[1000] -8 | [0111] 7 | [1000] -8 |
总结:
1)一个补码x的位表示取反后,其值为-x-1。因为-x的补码位表示比x的位表示取反多1。
2)-8为4位二进制int的INT_MIN,注意到x=-8,而-x也=-8,这是特殊情况,这里是因为正溢出了,具体原理见上一篇博客深入理解计算机系统》 练习题2.32。
例题:
计算补码0xfffffffa的十进制数值x。
那么直接利用本章原理,直接得到-x的补码位表示:过程如下
…1111 1010 (省略号代表好多个1,取反后为)
…0000 0101 (省略号代表好多个0,加1后为)
…0000 0110 (符号位在前面呢,后面的1都是正的权值)
所以-x = 4+2 = 6,既然-x=6,那么x = -6。
计算补码非:最右1之前取反
问题:给定一个数x的补码位表示,请给出-x的补码位表示。
原理:-x的补码位表示,即为前者中最右边的1之前的所有位取反(不包括最右1本身)。
示例表格:
[1100] -4 | [0100] 4 |
[1000] -8 | [1000] -8 |
[0101] 5 | [1011] -5 |
[0111] 7 | [1001] -7 |
[0000] 0 | [0000] 0 |
最右1被标注为斜体。
注意最后一行,因为没有一个1,所以没有位需要取反。