我们知道在C语言中,整型分为无符号整型(unsigned int)以及有符号整型(signed int),而他们存储在计算机中则都是以补码的形式存储的。
无符号整型没有符号位,其实也可以看成是以原码的形式存储在计算机中,毕竟正数的补码等于其原码。
下面分别以无符号整型和有符号整型来说明加减法
注:接下来的例子都是以8位二进制(其它位数都是大同小异的)来举例:
两个无符号整型相加,两个数的补码相加即可:[X]补+[Y]补=[X+Y]补
1+2=3 | 0000 0001 + 0000 0010 = 0000 0011 | 无溢出 |
|---|---|---|
255+1=0 | 1111 1111 + 0000 0001 = 0000 0000 | 溢出,超出8位则丢弃 |
两个无符号整型相减,看成是被减数加上减数的负数即可:[X]补-[Y]补=[X]补+[-Y]补=[X-Y]补
由[Y]补求[-Y]补的方法:[Y]补的所有位取反(包括符号位)再加1;
这个方法分解开解释:
当Y为正数时,存储在计算机中的补码也即原码,此时符号位取反相当于求原码的相反数(即负数),再把各个位取反再加1相当于求这个相反数的补码。 |
|---|
当Y为负数时,存储在计算机中的补码取反再加1相当于求原码,此时的原码是一个负数,再把符号位取反,相当于求这个负数的相反数(即正数),也是补码 |
1-2=255 | 0000 0001 + 1111 1110 = 1111 1111 | 无溢出 |
|---|---|---|
2-1=1 | 0000 0010 + 1111 1111 = 0000 0001 | 溢出,超出8位则丢弃 |
1-255=2 | 0000 0001 + 0000 0001 = 0000 0010 | 无溢出 |
以上无符号整型以"%d"输出时不考虑符号位,即把符号位当数据位一同输出;
两个有符号整型相加:[X]补+[Y]补=[X+Y]补
1+(-2)=-1 | 0000 0001 + 1111 1110 = 1111 1111 | 无溢出 |
|---|---|---|
2+(-1)=1 | 0000 0010 + 1111 1111 = 0000 0001 | 溢出,超出8位则丢弃 |
(-1)+(-1)=-2 | 1111 1111 + 1111 1111 = 1111 1110 | 溢出,超出8位则丢弃 |
127+1=-128 | 0111 1111 + 0000 0001 = 1000 0000 | 溢出符号位,此数补码表示-128 |
127+127=-2 | 0111 1111 + 0111 1111 = 1111 1110 | 溢出符号位 |
两个有符号整型相减:[X]补-[Y]补=[X]补+[-Y]补=[X-Y]补([Y]补求[-Y]补的方法同上面相同)
1-(-2)=3 | 0000 0001 + 0000 0010 = 0000 0011 | 无溢出 |
|---|---|---|
(-2)-(-1)=-1 | 1111 1110 + 0000 0001 = 1111 1111 | 无溢出 |
(-1)-(-1)=0 | 1111 1111 + 0000 0001 = 0000 0000 | 溢出,超出8位则丢弃 |
(-127)-1=-128 | 1000 0001 + 1111 1111 = 1000 0000 | 溢出,超出8位丢弃,此数补码表示-128 |
以上有符号整型以"%d"输出时需考虑符号位输出;
至此以例举出大多数的加减法例程,其它的数都是差不多的,重点在由[Y]补求[-Y]补上,自己多拿些数来算便能明白了,以上有出错的地方还请大神们指出,谢谢大家!
9660

被折叠的 条评论
为什么被折叠?



