O
Old Wolf
x == 0 ||
((x > 0 && y >= 0 || x < 0 && y <= 0) && INT_MAX / ABS(x) >= ABS(y)) ||
((x < 0 && y >= 0 || x > 0 && y <= 0) && (-INT_MIN) / ABS(x) >= ABS(y))
Is this one right?
No, (-INT_MIN) causes an integer overflow. You have to use
INT_MIN and negate the divisor (and get the inequality
direction right).
I would eschew the differentiation between INT_MIN and INT_MAX,
unless the code really did need to use INT_MIN as a valid value:
(x == 0) || (INT_MAX / ABS(x) > ABS(y))
Is there any way to implement ABS without evaluating the argument
twice? If not then I would make this an inline function.
Here's another way:
STATIC_ASSERT( sizeof(long long) >= 2 * sizeof(int) )
( 1LL * x * y <= INT_MAX && 1LL * x * y >= INT_MIN )
I wonder if any compiler would optimize:
if ( 1LL * ........ )
x *= y;
else
/* error handling */
to do a multiplication followed by an overflow check
(obv for CPUs which can overflow a multiplication and not trap).