Chinaunix首页 | 论坛 | 博客
  • 博客访问: 30623
  • 博文数量: 6
  • 博客积分: 167
  • 博客等级: 入伍新兵
  • 技术积分: 89
  • 用 户 组: 普通用户
  • 注册时间: 2011-10-28 20:14
文章分类

全部博文(6)

文章存档

2011年(6)

我的朋友
最近访客

分类: C/C++

2011-10-30 18:17:24

为了在计算机中表示负数,有一些编码方式添加了符号位来区别正整数与负整数,使得整数的加减运算变复杂了。

整数是一个整体,用符号位来区分正整数与负整数似乎没什么必要。

补码是一种编码方式,在这种编码方式中,正整数的表示方法跟无符号数相同是很自然的,可是负数怎么办呢?
为了简化这种编码方式的加减运算,希望可以把整数的减法[x]-[y]转换成加法[x]+[-y],用一个加法器来进行所有的加减运算,由于[x]+[-x]=[0],可以用正数来定义负数。
假定用4位二进制来编码,由于[0010]+[1110]=[0000],于是-2的编码是[1110]。类似的,可以给出其余负数的编码。

整理一下思路,以这样方式进行编码(8-bits)。
正整数与无符号数的编码相同(0~2^7-1)
用0与正整数(1~2^7)的编码来定义负整数的编码,使得[x]+[-x]=[0]
由负整数的定义可以看出,负数的编码是唯一的,同时值在2^7~2^8之间。
若x取反加1再加上自己,结果为0。x取反加1是唯一的,又由负整数的定义,负整数的编码一定是存在的,于是x取反加1就是负整数的编码。

这种编码的减法可以转换成加法
[x]-[y]=[x]-[y]+[0]=[x]+([0]-[y])=[x]+[-y]

对任何整数x与y有[x]+[y]=[x+y]
(i)如果x>0,y>0,[x]+[y]=[x+y]
(ii)如果x<0,y>0,x+y>0,[x]+[y]=[x]+[(x+y)+(-x)]=[x]+[x+y]+[-x]=[x+y](i)
(iii)如果x<0,y>0,x+y<0,[x]+[y]= [x]+[(x+y)+(-x)]=[x]+[x+y]+[-x]=[x+y](ii)
(iiii)如果x<0,y<0,[x]+[y]= [x]+[(x+y)+(-x)]=[x]+[x+y]+[-x]=[x+y](iii)
阅读(1938) | 评论(2) | 转发(0) |
0

上一篇:打印出自身的c程序

下一篇:并集查找算法

给主人留下些什么吧!~~

forlfs2018-04-14 21:17:47

在知乎上看到以下回答,转载一下:

很多人并不理解补码。补码就是同余啊。1000000是正128你知道吧,正负128模256是同余的。加减乘可以直接算也是同余的定理决定的,而不是凑出来的巧合,哪可能凑出这种东西?8位只能表示256个数,0到255,但我还想表示一些负数怎么办呢?就用与该负数同余的正数来表示呗。-1=255,-2=254,等等。建议脱离算数的思维方式,这其实就是一个环。模任何一个正整数(如256),可以把所有整数分类,比如模256可分256类,0 256 -256...是一类(余0类),1 257 -255...是一类(余1类),等等,这256类可看作环的元素,你看-128和128是同一个类里的(余128类),用一个代表另一个罢了。补码和普通的unsigned integers都是在每类中选一个数,unsigned integers选0到255,补码表示的有符号整数选-128到127,都是一个数恰好对应一个类。当你明白这一切后,补码就是顺理成章的事。练习:设计用8位二进制数表示13至268这256个数的方案。要求作加减乘运算的时候,可以直接把编码当正整数算,能得到正确结果。

链接:https://www.zhihu.com/question/28685048/answ

GFree_Wind2011-11-01 12:15:18

我喜欢这样的文章,越做,越觉得基础的重要。