Если попытаться применить операцию унарного минуса к числу типа int, содержащее INT_MIN, то ничего не изменяется.
Собственно сабж:
#include
int main (void)
{
int a = INT_MIN;
printf("a = %d
", a);
a = -a;
printf("a = %d
", a);
return 0;
}
Результат работы (компилятор - Clang):
a = -2147483648
a = -2147483648
В чем проблема?
P.S. стандарт c99 никакие ограничения (вроде) не накладывает:
6.5.3.3 Unary arithmetic operators
...
The result of the unary - operator is the negative of its (promoted) operand. The integer
promotions are performed on the operand, and the result has the
promoted type.
Ответ
-INT_MIN значение ведёт к неопределённому поведению (undefined behavior) в Си из-за переполнения (integer overflow). Это не только теоретическая проблема, к примеру
#define abs(x) ((x) > 0 ? (x) : -(x))
int foo(int x){
return abs(x) >= 0;
}
может быть скомпилировано в
mov eax, 1
ret
то есть даже для INT_MIN возвращается 1 вне зависимости от того как int представлен, то есть даже на реализациях где дополнительный код используется, где -n может вернуть INT_MIN
Переполнение возникает так как INT_MIN по модулю математически может быть больше INT_MAX
n == -n получается в дополнительном коде, так как унарный минус можно реализовать как: обратить биты, прибавить один: -n == ~n+1. К примеру, для 8-битного числа
n=-128 1000 0000
~n 0111 1111
~n+1 1000 0000
Комментариев нет:
Отправить комментарий