请解惑.unsigned int + int
unsigned int x = -1;
int y = 11;
int z = 10;
unsigned int uz = 10;
if(x+y == 10)
if(x+y == z)
if(x+y == uz)
x+y的计算是否引起溢出?
if语句是否能进入?
1.原理?
2.是否有编译器的差异. gcc, g++, vc?
[解决办法]
c++ primer里说:C++ 中,把负值赋给 unsigned 对象是完全合法的,其结果是该负数对该类型的取值个数求模后的值。当将超过取值范围的值赋给 signed 类型时,由编译器决定实际赋的值。在实际操作中,很多的编译器处理 signed 类型的方式和 unsigned 类型类似。也就是说,赋值时是取该值对该类型取值数目求模后的值。然而我们不能保证编译器都会这样处理 signed 类型。
[解决办法]
//有符号整形a和b,如何判断a+b是否溢出
#include <stdio.h>
int ifo_add(int a,int b) {
__asm {
mov eax,a
add eax,b
jo overflowed
xor eax,eax
jmp no_overflowed
overflowed:
mov eax,1
no_overflowed:
}
}
int main() {
int a,b;
a= 1;b= 2;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));
a= -1;b=-2;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));
a= 2147483647;b= 1;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));
a=-2147483647;b=-1;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));
a=-2147483647;b=-2;printf("%11d+(%2d) %d\n",a,b,ifo_add(a,b));
}
// 1+( 2) 0
// -1+(-2) 0
// 2147483647+( 1) 1
//-2147483647+(-1) 0
//-2147483647+(-2) 1
[解决办法]
那么题目可以转换为对 (unsigned int)-1 + (unsigned int)11 结果是否确定是10.
溢出后的确定是10?或者有编译器行为?
发生了溢出,结果确定是10,没有编译器行为,这是C语言标准行为。
编译器不做加法,编译器只是把加法代码转换成机器代码,最后由硬件(加法器)实现加法。