Вычитание без переполнения?

Предположим, что существуют два целых числа (int x, y;).
x отрицательно и y = 0x80000000.

Почему (x - y) не переполняется во время x + (-y)?
Разве компьютер не вычитается путем добавления?

Ответ 1

Чтобы ответить на ваш первый вопрос, 0x80000000 (-2,147,483,648) представляет собой минимальное 32-битное значение для целых чисел со знаком. 2,147,483,647 - максимальное значение. Величина максимального значения на единицу меньше величины минимального значения при сохранении с помощью Two Complement. Взятие только (-y) не может быть представлено, поскольку оно превышает максимальное значение (на 1). Конечное целочисленное значение (x-y) находится в диапазоне (учитывая, что x является отрицательным) и может быть представлено 32-разрядным целым.

Чтобы ответить на второй вопрос, вычитание достигается путем преобразования числа, которое должно быть вычтено в его аддитивном обратном. Учитывая возможность переполнения в этой ситуации, ваш компилятор может получить правильный результат для (x-y), выполнив -((-x)+y). Тем не менее, это чистая спекуляция (это единственный способ, которым я могу сделать это безопасно).