首页 > 代码库 > 补码的计算

补码的计算

对于程序猿或者是其它搞计算机类的人员,这篇只是为了解释一下原码,反码,补码之间的计算和解释上一篇的a + ~a = -1的问题!!!


  1. 首先先介绍一下整数在计算机中表示方法,数在计算机中都是用二进制表示,但是字节长度就不一定了,不同的机器可能就不一样

  2. 而且在计算机系统中,补码是最重要的编码,数值一律用补码来表示和存储

  3. 移码(又叫增码)是符号位取反的补码,一般用做浮点数的阶码,引入的目的是为了保证浮点数的机器零为全0

  4. 整数有正,有负的,所以计算机中为了表示正负,用字节的最高位来表示正负,其它位表示数值

  5. 例如大多数计算机体系中,(signed) int 就是一个有符号的数,占4个字节,signed可以不写,默认int就是signed int,另外signed默认也是signed int,不过这样写不规范,不建议这么写,

  6. 为了方便演示,下面就以一个字节为例!


  1. 正数的最高位是0,负数的最高位是1

  2. 正数原码和反码,补码都是一样的,都是正数本身

  3. 对于负数

  1. 原码是符号位为1,其它位和数本身的正数一样,也就是负数的原码等于其相反数的原码,但是最高位为1即可

  2. 反码就是在负数的原码基础上,符号位不变,其余的按位取反

  3. 补码就是在负数的反码基础上,符号位不变,加上1即可

 4. 从十进制求它二进制的原码,反码,补码就按上面的方法,但是知道一个补码怎么求数本身呢,对于正数不用求,因为就等于其本身(看符号位是否为0),但是对于符号位为1的补码,那就要再求一次补码了,过程是一样的,符号位不变,按位取反,最后加上1即可!然后算出其10进制的数的值再加上负号即可。下面举例子来说明一下!!!


eg:

7(10)-->0000 0111(2)  最高位0表示符号位,0表示正数

原码=反码=补码=0000 0111


-7(10)

原码:1000 0111(2)  最高位1表示为负数

反码:1111 1000(2)  在原码基础上符号位不变,其它的按位取反

补码:1111 1001(2)  在反码基础上符号位不变,再加上1

note:对于已经比较熟悉这些转换的人来说,就是~|-7|+1 即可!这个不作解释


已知补码求数本身---->1111 1011(2)-->?

note:方法就是再求一次其补码即可

1111 1011-->1000 0100 符号位不变,其它的按位取反

1000 0100-->1000 0101 符号位不变,再加上1 -->  -5(10)


好了现在可以回答上一篇《嵌入式c语言中的位运算》的问题了,假如是一个正数a的~a那么就是其它相反数的补码,但是没有加上1,所以比相反数少1(~a ==-a-1),所以和相反数-1相加就于-1,例如: a = 5, ~a + a =a+(-a -1) = -1 了!现在假如是一个负数,a = -5  1111 1011[补码](计算机中用补码表示整数) 把补码按位取反之后(包括符号位)为 0000 0100 正常情况下是符号位不变而且还要加上1的,但是这里没有加上1和保持符号位不变,所以就变成数本身的相反数-1了,也就是~a == -a-1,所以a+~a = a+(-a-1) = -1 

下面用程序来证明吧!

 1 #include <stdio.h>
  2 int main()
  3 {
  4         int a = 5;
  5         int b = ~a;
  6         int ret = a+b;
  7         printf("%d + %d = %d \n",a,b,ret);
  8 
  9         a = -22;
 10         b = ~a;
 11         ret = a + b;
 12         printf("%d + %d = %d \n",a,b,ret);
 13 }

wKioL1RQ1V3jNixiAAArqQmZLhI437.jpg


本文出自 “挑战自己” 博客,请务必保留此出处http://lovechocolate.blog.51cto.com/6757953/1569372

补码的计算