整数的加法、减法和乘法溢出判断
用c语言实现整数的加法、减法和乘法的溢出判断。
必要知识:
1. 在C语言中,对于任意整数值x,-x=~x+1;
2. 以32位机器为例,整型int的最小值 TMIN= 0x80000000.
/* Determine whether arguments can be added without overflow. */
/* If overflow, return 0 (otherwise 1)*/
int tadd_ok(int x, int y)
{
int sum = x+y;
int neg_over = x<0 && y<0 && sum>=0;
int pos_over = x>0 && y>0 && sum<0;
return !neg_over && !pos_over;
}
/* Determine whether arguments can be subtracted without overflow.*/
/* If overflow, return 0 (otherwise 1)*/
int tsub_ok(int x, int y)
{
if(y == ~y+1) // y == -y
return x<0;
else
return tadd_ok(x, -y);
}
注意:当y=TMIN=0x80000000时,-y=0x80000000并不是正的整数,所以此时不适用tadd_ok(x,-y).
证明:TMIN==-TIMIN.
-TIMIN = ~TMIN+1 = ~0x80000000+1 = 0x7FFFFFFF+1 = 0x80000000 = TMIN.
/* Determine whether arguments can be multiplied without overflow.*/
/* If overflow, return 0 (otherwise 1)*/
int tmult_ok(int x, int y)
{
int p = x*y;
return !x || p/x==y;
}
练习题:对于数据类型int为32的情况,设计一个版本的tmult_ok函数,要使用64位精度的数据类型long long,而不使用除法。
答案:
int tmult_ok(int x, int y)
{
/*Compute product without overflow*/
long long pll = (long long) x*y;
/*See if casting to int preserves value*/
return pll == (int )pll;
}