二进制整数的加,减运算

二进制整数的加,减运算

 

前言

在平时的编程中,当进行整数运算时,经常会遇到一些奇怪的结果,比如两个正数相加出现了负数,两个负数相加出现了正数,这些都是因为数值表示的有限性导致的.来看一个案例:

            int a = 0x7FFFFFFF;

            int b = 0x7FFFFFFF;

            

            Console.WriteLine(a);

            Console.WriteLine(b);

            Console.WriteLine(a+b);

我这是C#的代码,我告诉你输出结果吧:-2

程序中的ab都是很大的正整数,结果它们相加会得到一个负数.

 

再看看用C语言写的代码:

#include <stdio.h>

 

int main(){

    int a = 0x7FFFFFFF;

    int b = 0x7FFFFFFF;

    printf("%d\n",a);

    printf("%d\n",b);

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

}

输出结果也是-2

这是咋个回事呢?下面跟随你单哥咱们一起探个究竟!

 

 

 

无符号加法

 

记得小时候杂学的加法把?我们都是使用的图画表示,就是上面是加数下面是加数,左边一个加号,逢十进一,然后下面一条横线,横线下面是结果.想起来了吧

 

对于二进制整数来说,其实是可以用这种最原始的方式去计算,由此也可以认识到,二进制整数的加法也是非常简单的.只不过与我们平时的十进制算法有一个最大的区别,那就是我们在计算机当中进行计算时,结果的位数都是有限制的.因此我们计算完成后,可能需要对结果进行截断操作.

 

前面一节咱们刚说了有关阶段的内容,那么明显这里就这样用上了.这里使用的时候有一个前提,我们可以假设是进行w位的二进制运算,那么在运算之后的实际结果也一定是w位的.这里有两种情况,一种结果依然是w位的,也就是w+1位为0.第二种则是到达了w+1,这个时候我们需要将结果截断到w.(明白不?就是3+39+9的案例,一个是6,6是一位,一个是18,18是两位,还不明白,我建议你从事别的专业吧,计算机可能不太适合你...)

 

第一种情况属于正常的加法运算,对于第二种来说,我们根据上一张的结论,假设完整的结果为sum,则实际的结果最终为sum mod 2w。

在书中给出了一个公式,它得到了这个结果的一个前提是两个操作数都满足小于2w,它与我们上面取模的结果其实是一样的。


 

再稍微解释一下,对于第一种情况,x+y < 2w,则sum mod 2w是与sum一致的。对于第二种来说,当 2w =< x+y < 2w+1,对 x + y 进行2w的取模运算,与 x + y - 2w是等价的。

 

 

 

 

无符号的非

无符号的加法会形成一个阿贝尔群,这意味着无符号的加法满足一些特性.比如说可交换,可结合等等.在这个群中,单位元为0,那么每一个群中的元素,就是每一个无符号数u,都会拥有一个逆元u-1,满足 u+ u-1 = 0。这个结论的来源是,对于w位上的无符号运算来讲,倘若两个无符号数的加法运算结果为2w,也就是1后面跟w0,此时截断之后的结果则为0

从以上的简单分析,我们可以很容易的得到一个无符号数的逆元满足以下公式(公式中的左边就是我写的u-1,由于图中的符号在博文中不好编辑,所以我以u-1替代)。

 

 

 

 

 

 

补码加法       

对于不骂的加法来讲,我们会建立在无符号假发的基础上来进行,这么做的一个重要前提是,他们的位表示都是一样的.

 

其实补码加法就是先按照无符号加法进行运算,而后再进行无符号和有符号的的转换.因此我们根据上面的结论可得,对于两个补码编码的有符号数来说,他们进行加法运算的最终结果为,假设实际的无符号结果为sum,那么最终的实际结果为:

U2Tw(sum mod 2w)。

上面这个结论看起来很简单,但是实际上它的运算结果还是比较复杂的,树中给出了四种情况的分析,采用数学推导和证明的方式来说明.

 

与无符号加法不同的是,这里会出现三种结果,一种是正常的结果,一种是正溢出,一种数负溢出.

 

对于正溢出的时候,我们的结果与无符号数类似,取模之后等价于减去2w次方.而当负溢出的时候,则刚好相反,取模之后的结果等价于加上2w次方.更直观的,由于我们最终科表示的补码范围在-2w-1(包含)到2w-1之间,所以我们总是要试图将最终的实际结果报纸在这个范围之内.于是我们可以直观的得到下面的结果

 

 

 

补码的非

 

对于补码来说,它同样的与无符号有一样的特性,也就是对于任意的一个w位的补码t来说,他都有唯一的逆元t-1次方,是的t+t-1次方=0.

一个w位的补码数范围在-2w-1次方(包含)2w-1次方之间,直观的可以看出,对于不等于-2w-1次方的补码数x来说,他的逆元就是-x.而对于-2w-1次方来说,他的二进制位表示为1后面跟着w-10,我们需要找到一个数与其相加之和结果为0.

这种时候我们需要考虑的是,如果是-x,也就是2w-1次方,则它的位表示需要w+1,是不存在.因此我们需要考虑溢出的情况,对照上面的公式2.14,负溢出的时候需要加上2w次方,因此-2w-1次方的逆元就是-2w次方+2w-1次方=-2w-1次方,也就是他本身.

综上,最终我们可以得到补码的逆元满足以下公式(这里与上面一样,公式左边是我们所说的逆元t-1次方).

 

 

 

 

二进制整数的减法

减法运算器是是可以由加法运算替代的,我们上面已经介绍过了无符号和补码的非,其实很多CPU是没有减法运算器的,他们都是将减数进行逆运算以后送入加法器,然后进行加法运行,这样得出来的结果就是减法运算最终的结果.

 

 

比如我们考虑一种简单的情况,w=4时的无符号减法运算,对于5-4这个减法运算来说,我们可以由5+4-1次方(其中4-1次方是4的逆元的意思,不是四分之一的意思)来替代这个减法运算.

 

为了更加直观,咱们一起来算一下,首先4的逆元根据上面的公式可以得到4-1次方=24次方-4=12.呢么我们现在需要对512进行加法运算,他们的位分别表示为01011100,结果为10001,就是十进制17的位表示.不过由于我们的w=4,因此截断之后结果为0001,就是十进制的1.最终结果得到5-4=1.

 

对于5-4来说,是考虑的结果为正的情况.或许有人认为会对结果为负或者说无符号数移除的情况下有疑问,因此咱在这里对这种情况也做了一个简单的介绍.我们考虑一个简单的计算0-1,我们可以得到1-1次方=24次方-1=15.此时对015进行加法计算,他们的位表示分别为00001111,结果为1111.

看到这里估计有人会有疑问了,这是怎么回事,0-1=15?

当然不是,,,这个结果其实是正确的.考虑使用补码编码来解析1111这个位表示,它代表的值就是-1.151111这个位表示在无符号编码情况下的解析结果.

 

因此这里有一个公式,就是对于两个整数xy来说,x-y=x+y-1次方,这个公式代表的意义是位表示,而不是实际的数值.

 

 

 

小结

主要讲解了二进制整数的加法运算,还有减法的简单介绍.

 

 

 

 

 

 


 

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值