Вопрос

I know that (INT_MIN / -1) overflows, but (INT_MIN % -1) does not. At least this is what happens in two compilers, one pre-c++11 (VC++ 2010) and the other post-c++11 GCC 4.8.1

int x = INT_MIN;
cout << x / -1 << endl; 
cout << x % -1 << endl;

Gives:

-2147483648
0

Is this behavior standard defined or this is implementation defined? Also is there ANY OTHER case where the division operation would overflow? and is there any case where the modulus operator would overflow?

Это было полезно?

Решение

According to CERT C++ Secure Coding Standard modulus can can overflow it says:

[...]Overflow can occur during a modulo operation when the dividend is equal to the minimum (negative) value for the signed integer type and the divisor is equal to -1.

and they recommend the follow style of check to prevent overflow:

signed long sl1, sl2, result;

/* Initialize sl1 and sl2 */

if ( (sl2 == 0 ) || ( (sl1 == LONG_MIN) && (sl2 == -1) ) ) {
  /* handle error condition */
}
else {
  result = sl1 % sl2;
}

The C++ draft standard section 5.6 Multiplicative operators paragraph 4 says(emphasis mine):

The binary / operator yields the quotient, and the binary % operator yields the remainder from the division of the first expression by the second. If the second operand of / or % is zero the behavior is undefined. For integral operands the / operator yields the algebraic quotient with any fractional part discarded;81 if the quotient a/b is representable in the type of the result, (a/b)*b + a%b is equal to a; otherwise, the behavior of both a/b and a%b is undefined.

The C version of the CERT document provides some more insight on how % works on some platforms and in some cases INT_MIN % -1 could produce a floating-point exception.

The logic for preventing overflow for / is the same as the above logic for %.

Другие советы

It is not the modulo operation that is causing an overflow:

int x = INT_MIN;
int a = x / -1; // int's are 2's complement, so this is effectively -INT_MIN which overflows
int b = x % -1; // there is never a non-0 result for a anything +/- 1 as there is no remainder

Every modern implementation of the C++ language uses two's complement as the underlying representation scheme for integers. As a result, -INT_MIN is never representable as an int. (INT_MAX is -1+INT_MIN). There is overflow because the value x/-1 can't be represented as an int when x is INT_MIN.

Think about what % computes. If the result can be represented as an int, there won't be any overflow.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top