Целое число переполняется, когда 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;
}