C语言原码、反码与补码学习

  一、什么是原码、反码和补码

  我们知道,在计算机内部存储的带符号数都是以补码形式存储,用补码形式进行运算的。什么是一个数的补码?为什么要用补码?这要从数的原码、反码开始讲。我们以整型数为例,且假定字长为8位。

  1、原码

  整数X的原码是指:其符号位为0表示正,为1表示负;其数值部分就是X的绝对值的二进制数。X的原码通常用【X】原表示。如:

  【+100】原=01100100 【+0】原=00000000

  【-100】原=11100100 【-0】原=10000000注意:在原码中,零有两种表示形式。

  原码表示法简单易懂,与真值(带符号数本身)转换方便,只要符号还原即可,但当两个正数相减或不同符号数【】相加时,必须比较两个数哪个绝对值大,才能决定谁减谁,才能确定结果是正还是负,所以原码不便于加减运算。

  2、反码

  X的反码是指:对于正数,反码与原码相同;对于负数,符号位不变,其数值位X的绝对值取反(1变0,0变1)。X的反码通常用【X】反来表示。如

  【+100】反=01100100 【+0】反=00000000

  【-100】反=10011011【-0】反=11111111

  注意:在反码中,零也有两种表示形式。

  反码运算也不方便,通常用来作为求补码的中间过渡。

  3、补码

  X的补码是指:对于正数,补码与原码相同;对于负数,符号位不变,其数值位X的绝对值取反后在最低位加1。X的补码通常用【X】补来表示,实际上,【X】补=【X】反+1。如:

  【+100】补=01100100 【+0】补=00000000

  【-100】补=10011100 【-0】补=00000000

  注意:在补码中,零有唯一的编码,【+0】补=【-0】补=00000000。

  补码运算简单方便,符号位可以作为数据的一位参与运算,不必单独处理;二进制的减法可用其补码的加法来实现,简化了硬件电路。

  二、补码的意义

  首先,我们来看几个例子。

  【例子1】用8位二进制数分别表示+0和-0 。

  解:我们知道,对于有符号数,我们规定最高位为符号位,0表示正数,1表示负数。剩余位为数值位,用来表示数的大小。

  所以+0就表示为0000 0000,而-0表示为1000 0000。

  【例子2】计算9-6的结果。

  解:我们知道:9-6=9+(-6)=3

  0000 1001

  +1000 0110

  1000 1111

  结果为-15,明显不对。

  而如果我们采用补码来进行计算呢?

  我们知道,9的补码是0000 1001,-6的补码是11111010,重新进行运算,

  0000 1001

  +1111 1010

  1 0000 0011

  最高位的1溢出,剩余8位二进制表示的是3的补码。结果为3,正确。

  【例子3】分析程序运行结果。

  main()

  {int a=100,b=-1;

  Printf(“a=%d,%x,%o,%un”,a,a,a,a);

  Printf(“b=%d,%x,%o,%un”,b,b,b,b);}

  运行结果:

  a=100,64,144,100

  b=-1,ffff,177777,65535

  【例子1】中,为什么同样一个0有两种不同的表示方法呢?

C语言原码、反码与补码学习

  【例子2】中,为什么第一种计算方法会错,而用补码计算结果才对呢?

  而【例子3】中,为什么-1以十六进制、八进制以及无符号整型输出的结果分别变成了ffff,177777,65535?

  这是因为在计算机系统中,数值一律用补码来表示(存储)。

  主要原因:

  1、统一了零的编码;

  2、将符号位和其它数值位统一处理;

  3、将减法运算转变为加法运算;

  4、两个用补码表示的数相加时,如果最高位(符号位)有进位,则进位被舍弃。

  三、补码的计算

  1、定义法:

  (1)正数的补码:与原码相同。

  【例1】+9的补码是00001001。

  (2)负数的补码:符号位为1,其余位为该数绝对值的原码按位取反;然后整个数加1。

  【例2】求-9的补码。

  因为给定数是负数,则符号位为“1”。

  后七位:+9的原码(0001001)→按位取反(1110110)→加1(1110111)

  所以-7的补码是11110111。

  2、查零法

  原码是用1来表示数值的大小,属于正逻辑,对原码的计算我们主要是计算1的个数;而反码和补码是用0来表示数值的大小,属于负逻辑,所以我们可以采取逆向逻辑思维来理解,通过计算0的个数来求负数的补码。由于补码是在反码的基础上加了一个1,所以0的个数应该比原数的绝对值小1。

  例如:求-5的补码

  零的个数应为4个,所以-5的补码为:11111011。

  再如:求-97的补码

  零的个数应为96个,96=64+32,对应的权值位为0,其余位为1。所以-97的补码为:10011111。

  3、零减法

  负数的补码=全零-正数的原码,如-5的补码=0-5的原码。

  用该数的十六进制计算,得到的结果转换为二进制即可。

  例如:求-5的补码

  算法1:算法2:

  00000000 00H

  ﹣00000101 ﹣05H

  11111011 0 FBH

  4、找1法

  例如:求-15的补码

  第一步:+15:00001111

  第二步:从右向左找到第一个1,然后把左边的所有位取反。

  11110001

  再举一个例子验证下:求-64的补码

  +64:01000000

  11000000

  四、几点补充

  1、已知一个数的补码,求原码的操作分两种情况:

  (1)如果补码的符号位为“0”,表示是一个正数,其原码就是补码。

  (2)如果补码的符号位为“1”,表示是一个负数,那么求给定的这个补码的补码就是要求的原码。

  【例3】已知一个补码为11111001,则原码是10000111(-7)。

  因为符号位为“1”,表示是一个负数,所以该位不变,仍为“1”。

  其余七位1111001取反后为0000110;

  再加1,所以是10000111。

  2、数值范围

8位二进制原码所表示数的范围是-127~+127;

一、原码表示法

  除了符号位外,其他二进制位为数值的绝对值,这种方案称为“原码”表示法。例如:

  +20的原码:0 000 0000 0001 0100

  -20的原码: 1 000 0000 0001 0100

二、反码表示法

  除了符号为以外,负数的反码表示是在原码的基础上其他二进制取反,而正数的反码表示与原码相同。如:

  +20的反码为: 0 000 0000 0001 0100

  -20的反码为: 1 111 1111 11101011

三、补码表示法

  负数的补码表示是在反码基础上加1,而正数的反码表示与原码相同

四、为什么计算机一般采用补码表示法

  原码、反码和补码是由于表示负数的三种方案,三种方案中,原码最适合与乘除类运算,补码适合于加减类运算,而反码则加减与乘除都不是很理想,由于加减运算的频率远高于乘除运算,所以多数计算机系统采用的是补码方案。

  所以所有计算机的加减运算都要将相应的数转换成补码,然后再进行运算

  

爱华网本文地址 » http://www.413yy.cn/a/25101015/243273.html

更多阅读

转载 C语言:随机函数rand()、srand()、random()和rando

原文地址:C语言:随机函数rand()、srand()、random()和randomized()的区别和用法作者:猎空声明一点:在VC++中,没有random()和randomize()函数,只有rand()和srand()函数。其中,random()和randomize()函数的使用的方法分别与rand()和srand()

C语言在K叉哈夫曼编码教学中的应用 c语言哈夫曼编码译码

摘 要:字符编码与信息压缩是计算机应用的重要研究课题,许多学者对此作了很多非常有价值的研究。文章简单分析了二叉哈夫曼树的构造及编码,通过比较三种构造三叉哈夫曼树的算法,提出了构造任意K叉哈夫曼树及K进制的最优前缀编码的算法,并

C语言视频教程30课曾怡 c语言教学视频曾怡

最好的c语言视频教程----曾怡副教授讲解30课,csf格式C程序设计视频教程(曾怡):本套视频教程由曾怡副教授讲解,使用教材为:《C语言程序设计》 谭浩强清华大学出版社出版。是难得的C语言学习视频教程。全程共30讲,每讲45分钟左右,CSF视频格

声明:《C语言原码、反码与补码学习》为网友我懂了分享!如侵犯到您的合法权益请联系我们删除