整数运算的溢出 gaunthan Posted on May 14 2016 ? The Representation and Storage of Information ? ## 无符号整型相加的溢出 位数为$w$位的无符号整型数$x$和$y$,如果$x + y < 2^w$,则和的$w+1$位表示中的最高位会等于0,因此丢弃它不会改变这个数值。另一方面,如果$2^w \le x + y \lt 2^{w+1}$,则和的$w + 1$位表示中的最高位会等于1,因此丢弃它就相当于从和中减去了$2^w$。故可以得出以下关系($s = x + y$): * 如果$s$没有溢出,则必定有$s \ge x$; * 否则,必定有$s = x + (y - 2^w) \lt x$ 因此,根据上述特点可写出以下测试代码: ```c /** * 相加没有溢出则返回1,否则,返回0 */ inline int UAddOK(unsigned int x, unsigned int y) { return (x + y) < x ? 0 : 1; } ``` ## 补码加法的溢出 补码加法有两种溢出情况,分别是: * 正溢出。两个正数相加得到负的和。 * 负溢出。两个负数相加得到正的和。 因此可写成以下测试代码: ```c /** * 相加没有溢出则返回1,否则,返回0 */ inline int TAddOk(int x, int y) { int s = x + y; if( (x < 0 && y < 0 && s > 0) || (x > 0 && y > 0 && s < 0) ) return 0; else return 1; } ``` ## 补码乘法的溢出 ```c /* 测试两符号数相乘是否溢出。是,返回1;否则返回0 */ int TMultOk(int x, int y) { int p = x * y; return !x || p/x == y; /* 用除法来检验乘法是否溢出 */ } ``` ## References - RandalE.Bryant, DavidR.O’Hallaron, 布赖恩特,等. 深入理解计算机系统[M]. 机械工业出版社, 2011. 赏 Wechat Pay Alipay 数据对齐 存储单元与字节顺序