我最近一直在搞弄C语言,并提出了整数重载的概念。我正在尝试创建一个程序,该程序检测两个相乘的32位整数是否能够适合另一个32位整数。
我了解整数溢出的概念以及整数最终如何溢出,但是我仍然想弄清楚该程序的逻辑。这是我到目前为止的内容:
int main() {
int min = INT_MIN;
int max = INT_MAX;
int num1, num2;
int x = num1 * num2;
printf("Please enter a number you would like to multiply: ");
scanf("%d", &num1);
printf("\nPlease enter a second number you would like to multiply: ");
scanf("%d", &num2);
if (num1 > max / num2){
printf("\nOverflow! - first case\n");
}
else if (num2 > max / num1){
printf("\nOverflow! - second case\n");
}
else if ((num1 > max - num2 && num2 > 0 ) ||
(num1 < max - num2 && num2 < 0)){
printf("\nOverflow! - third case\n");
}
else
printf("\nNot Overflow!\n");
return 0;
}
如您所见,我的程序可以检测到某些情况下的溢出情况,但其他一些情况(例如-2 * 3和-2 * -3)会被我的情况捕获。
所以我拥有的绝对无法使用。有什么好的方法可以解决这个问题?
答案 0 :(得分:2)
当a*b > INT_MAX
或a*b < INT_MIN
时,整数溢出。
这导致不等式:
如果b > 0
:a > INT_MAX/b
或a < INT_MIN/b
如果b < 0
:a < INT_MAX/b
或a > INT_MIN/b
因此,如果int
溢出,则输出的条件是:
b>0 && (a>INT_MAX/b || a<INT_MIN/b) || b<0 && (a<INT_MAX/b || a>INT_MIN/b)
由于INT_MIN/b
可能会自身溢出(b=-1
时),因此应单独检查。
这是一个相当长的条件,应该拆分并放入一个函数中
int ismultoverflow(int a, int b)
{
if(b > 0)
{
if(a>INT_MAX/b || a<INT_MIN/b)
{
return 1;
}
}
else if(b < 0)
{
if(b == -1)
{
return a==INT_MIN;
}
if(a<INT_MAX/b || a>INT_MIN/b)
{
return 1;
}
}
return 0;
}
另一种方法是将不等式分为四个域而不是两个域:
如果a > 0
和b > 0
:a > INT_MAX/b
如果a > 0
和b < 0
:b < INT_MIN/a
如果a < 0
和b > 0
:a < INT_MIN/b
如果a < 0
和b < 0
:b < INT_MAX/a
导致无需处理特殊情况的函数:
int ismultoverflow(int a, int b)
{
if(a>0 && b>0 && a>INT_MAX/b)
{
return 1;
}
if(a>0 && b<0 && b<INT_MIN/a)
{
return 1;
}
if(a<0 && b>0 && a<INT_MIN/b)
{
return 1;
}
if(a<0 && b<0 && b<INT_MAX/a)
{
return 1;
}
return 0;
}
当然,如果您可以使用更大宽度的类型,则它的复杂程度将降低(不能保证long
或long long
比int
宽,但是在许多平台上,这是情况):
int ismultoverflow(int a, int b)
{
long x=a, y=b;
if(x*y > INT_MAX || x*y < INT_MIN)
{
return 1;
}
return 0;
}