Страницы

Поиск по вопросам

пятница, 13 декабря 2019 г.

Не работает унарный минус на INT_MIN

#c #операторы


Если попытаться применить операцию унарного минуса к числу типа int, содержащее INT_MIN,
то ничего не изменяется.

Собственно сабж:

#include 
#include 

int main (void)
{
    int a = INT_MIN;

    printf("a = %d\n", a);
    a = -a;
    printf("a = %d\n", 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.

    


Ответы

Ответ 1



-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

Комментариев нет:

Отправить комментарий