源码,反码,补码

 
一、原码 

求原码的方法:设X;若X≥0,则符号位(原码最高位)为0,X其余各位取值照抄;若X≤0,则符号位为1,其余各位照抄。 
【例1】X=+1001001   [X]原 = 01001001 
【例2】X=-1001001   [X]原 = 11001001 

二、反码 

求反码的方法:设X;若X≥0,则符号位(原码最高位)为0,X其余各位取值照抄;若X≤0,则符号位为1,其余各位按位取反。 
【例3】X=+1001001   [X]反 = 01001001 
【例4】X=-1001001   [X]反 = 10110110 

三、补码 

求补码的方法:设X;若X≥0,则符号位(原码最高位)为0,X其余各位取值照抄;若X≤0,则符号位为1,其余各位按位取反后,最低位加1。 
【例5】X=+1001001   [X]补 = 01001001 
【例6】X=-1001001   [X]补 = 10110111 

四、补码加减法 
   计算机中实际上只有加法,减法运算转换成加法运算进行,乘法运算转换成加法运算进行,除法运算转换成减法运算进行。用补码可以很方便的进行这种运算。 

1、补码加法 
   [X+Y]补 = [X]补 + [Y]补 
【例7】X=+0110011,Y=-0101001,求[X+Y]补 
    [X]补=00110011  [Y]补=11010111 
    [X+Y]补 = [X]补 + [Y]补 = 00110011+11010111=00001010 
    注:因为计算机中运算器的位长是固定的,上述运算中产生的最高位进位将丢掉,所以结果不是 
        100001010,而是00001010。 

2、补码减法 
   [X-Y]补 = [X]补 - [Y]补 = [X]补 + [-Y]补 
   其中[-Y]补称为负补,求负补的方法是:对补码的每一位(包括符号位)求反,最后末位加“1”。 
【例8】X=+0111001,Y=+1001101,求[X-Y]补 
    [X]补=00111001  [Y]补=01001101  [-Y]补 = 10110011 
    [X-Y]补 = [X]补 + [-Y]补 = 00111001+10110011=11101100 

五、数的表示范围 
    通过上面的学习,我们就可以知道计算机如果用一个字节表示一个整数的时候,如果是无符号数,可以表示0~255共256个数(00000000~11111111),如果是有符号数则能表示-128~127共256个数(10000000~01111111)。如果两个字节表示一个整数,则共有65536个数可以表示,大部分程序设计语言中整数的范围都是-32768~32767的原因,可以看出这种整数类型是16位的有符号数,而且是补码表示的。
 
 
 
 

1、原码、反码和补码的表示方法

      (1)原码:在数值前直接加一符号位的表示法。

                  [+7]原=   0    0000111  B
                  [-7] 原=   1    0000111  B
         注意:
                 a. 数0的原码有两种形式: [+0]原=00000000B    [-0]原=10000000B
                 b.8位二进制原码的表示范围:-127~+127
 

(2)反码:
          正数:正数的反码与原码相同。
          负数:负数的反码,符号位为“1”,数值部分按位取反。
           
         例如: 符号位 数值位
                     [+7]反=  0   0000111  B
                     [-7]反=  1   1111000   B
         注意:
                 a. 数0的反码也有两种形式,即 [+0]反=00000000B  [- 0]反=11111111B
                 b.8位二进制反码的表示范围:-127~+127
 
 

(3)补码:
              在计算机系统中,数值一律用补码来表示(存储)。 
              主要原因:使用补码,可以将符号位和其它位统一处理;同时,减法也可按加法来处理。另外,两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。 
             数值的补码表示也分两种情况: 
                      正数:正数的补码和原码相同。
                      负数:负数的补码则是符号位为“1”,数值部分按位取反后再在末位(最低位)加1。也就是“反码+1”。

            例如:
                   [+7]补=   0   0000111  B
                    [-7]补=   1   1111001  B

 2 、已知一个数的补码,求原码的操作分两种情况: 
              (1)如果补码的符号位为“0”,表示是一个正数,所以补码就是该数的原码。 
               (2)如果补码的符号位为“1”,表示是一个负数。按照求负数补码的逆过程,数值部分应是最低位减1,然后取反。但是对二进制数来说,先减1后取反和先取反后加1得到的结果是一样的,故仍可采用取反加1 。 
              例:已知某数X的补码11101110B,试求其原码。
                      解:由[X]补=11101110B知,X为负数。求其原码表示时,符号位不变,数值部分按位求反,再在末位加1。
                               1  1  1  0  1  1  1  0   补码 
                               1  0  0  1  0  0  0  1   反码,符号位不变,数值位取反+1
                               1  0  0  1  0  0  1  0   原码
 
            若字长为8位,则补码所表示的范围为-128~+127。这是一个规定, 10000000这个补码表示的这个数是-128。所以n位补码能表示的范围是-2^(n-1)到2^(n-1)-1,比n位原码能表示的数多一个。

            byte类型的范围:(负数最小值,1既是符号位又是值位) 
Dec:             -128                              -1                              0                              127 
Bin:          1000 0000                  1111 1111             0000 0000                   0111 1111
32位Int类型范围: 
Dec:       -2147483648                     -1                            0                            2147483647                
Hex:       0x80000000              0xFFFFFFFF              0x00000000                  0x7FFFFFFF

3、溢出
       两个有符号数进行加法运算时,如果运算结果超出可表示的有符号数的范围时,就会发生溢出,使计算结果出错。很显然,溢出只能出现在两个同符号数相加或两个异符号数相减的情况下。
       对于加法运算,如果次高位(数值部分最高位)形成进位加入最高位,而最高位(符号位)相加(包括次高位的进位)却没有进位输出时,或者反过来,次高位没有进位加入最高位,但最高位却有进位输出时,都将发生溢出。因为这两种情况是:两个正数相加,结果超出了范围,形式上变成了负数;两负数相加,结果超出了范围,形式上变成了正数。

      而对于减法运算,当次高位不需从最高位借位,但最高位却需借位(正数减负数,差超出范围),或者反过来,次高位需从最高位借位,但最高位不需借位(负数减正数,差超出范围),也会出现溢出。

  1. #include <iostream>  
  2. #include <cstring>  
  3. using namespace std;  
  4.   
  5. int main(){  
  6.     int a = 0x7fffffff;  
  7.     int b = 1;  
  8.   
  9.     printf("%x\n", a);  
  10.     printf("%d\n", a);  
  11.       
  12.     printf("%x\n", a + 1);  
  13.     printf("%d\n", a + 1);  
  14.   
  15.     system("PAUSE");  
  16.     return 0;  
  17. }  
#include <iostream>
#include <cstring>
using namespace std;

int main(){
	int a = 0x7fffffff;
	int b = 1;

	printf("%x\n", a);
	printf("%d\n", a);
	
	printf("%x\n", a + 1);
	printf("%d\n", a + 1);

	system("PAUSE");
	return 0;
}

结果:

7fffffff
2147483647
80000000
-2147483648

 
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值