无符号二进制整数的减法运算例子
上面的4个减法例子,都没有发生下溢(小于最小值0即负数),但两个【无符号二进制整数】相减是会发生下溢的,下溢后计算机硬件选择将溢出的位去掉,将剩下的所有位作为结果,如下图
无符号二进制整数的下溢运算例子
【无符号二进制整数】下溢发生在一个小的数减去大的数,如上图01100011=99,10110000=176,99-176=-77,采用传统的运算,小数减去大数规则就是大数-小数即10110000-01100011,然后对结果加上符号,计算机不能这么算,因为这里是无符号运算,不能有负数,因此很多计算机硬件选择直接用01001101即77作为结果,忽略掉负号。
对于常见的程序语言c,c 是支持【无符号二进制整数】的,java没有【无符号二进制整数】,只支持【有符号二进制整数】,另外【无符号二进制整数】编码是唯一性的,不存在同一个【无符号二进制整数】对应不同的二进制编码。
1.2 【有符号二进制整数】的运算【有符号二进制整数】的编码规则有3种即原码,反码,补码,在几乎所有的计算机硬件加减运算中采用的是补码,先上一个图来区分一下【无符号二进制整数】,原玛,反码,补码的区别,如下面的表格采用4位二进制。
二进制 | 无符号 | 原码 | 反码 | 补码 |
0000 | 0 | 0 | 0 | 0 |
0001 | 1 | 1 | 1 | 1 |
0010 | 2 | 2 | 2 | 2 |
0011 | 3 | 3 | 3 | 3 |
0100 | 4 | 4 | 4 | 4 |
0101 | 5 | 5 | 5 | 5 |
0110 | 6 | 6 | 6 | 6 |
0111 | 7 | 7 | 7 | 7 |
1000 | 8 | -0 | -7 | -8 |
1001 | 9 | -1 | -6 | -7 |
1010 | 10 | -2 | -5 | -6 |
1011 | 11 | -3 | -4 | -5 |
1100 | 12 | -4 | -3 | -4 |
1101 | 13 | -5 | -2 | -3 |
1110 | 14 | -6 | -1 | -2 |
1111 | 15 | -7 | -0 | -1 |
如上面的表格所示,同一个二进制采用不同的编码方式,表示的十进制数是不一样,另外,原码,反码,补码都可以表示【有符号二进制整数】,它们的最高位都是符号位,1表示负数,0表示正数,正数的编码都相同,负数的编码各个不同,下面来看看原码,反码,补码的定义。
原码:
最高位为符号位,1表示负数,0表示整数,剩余的位数按照【无符号二进制整数】转化为十进制,例如4位二进制数1001,最高位为1,剩余的位数为001按照【无符号二进制整数】转化为十进制就是1,所以结果为-1,原码的值的计算公式如下图
原码值转化为十进制
以0001,0101,1011,1111为例子,按照上面公式计算如下图所示
原码值转化为十进制例子
反码:
最高位为符号位,1表示负数,0表示整数,对于负数,剩余的位数取反后,再按照【无符号二进制整数】转化为十进制,例如4位二进制数1001,最高位为1,剩余的位数为001,取反后就是110,110按照【无符号二进制整数】转化为十进制就是6,所以结果为-6,反码的值的计算公式如下图