代码改变世界

有符号和无符号数回绕问题(补码加法和补码减法)

2013-08-04 02:22  youxin  阅读(3187)  评论(0编辑  收藏  举报

我们知道,在有符号数中,最小值-1=最大值,最大值-1=最小值。我们称之为回绕wrap around现在来说一般建议避免,因为其他架构的CPU,发生整数溢出时可能会触发CPU异常。

无符号最大值+1=0.

可见,无符号和有符号都会回绕。

为什么最小值-1=最大值。这要从计算机内部数字表示形式开始,都是采用补码表示。

补码表示有一些好处,统一了0([0]补=0000;).把减法都可以转换为加法。

补码加法:

[x]补+[y]补=[x+y]补                   (mod 2^(n+1))(证明略)。

例:x=+1011;y=-0101;求x+y;

解:[x]补=01011;[y】补=11011;

 [x]补    01011

 [y]补    11011

===========

[x+y]补     (进位1丢掉)00110

结果为x+y=+0110; 

补码加法的特点:1是符号位要作为数的一部分参与运算,而是要在模2^(n+1)的意义下相加,即超过2^(n+1)要丢掉

补码运算符号位要参与运算。

 

(我们前面说的无符号最大值+1=0.可以这样理解,假设为 unsigned char

 

a=0xff; a+1 0xff+0x01=0x00(前面的进位丢掉了)。

 更深入参考:http://zh.wikipedia.org/wiki/%E8%A1%A5%E7%A0%81

 

补码减法

负数的加法要利用补码转为加法来做。

【x-y]补=[x]补-[y]补=[x]补+[-y]补 ( -[y】补=[-y]补)

例:

 x=+1101;y=+0110;求x-y;

[x]补=01101;

[y]补=00110;

[-y]补=11010;

[x]补        01101

[-y]补       11010

===========

   (进位 1)00111

所以x+y=+0111;

 

溢出概念与检测方法:

在定点机器中,数的表示范围|x|<(2^n-1).在运算过程中如出现大于字长绝对值的现象,称为“溢出”,在定点机器中,正常情况下

溢出是不允许的

例:x=+1011,y=+1001;求x+y

  [x]补            01011

 【y】补          01001

=============

                      10100

2个正数相加的结果成为负数,显然是错误的。

参考:计算机组成原理:白中英。