Для вашего вопроса важная часть цитаты, которую вы включили, такова:
Отрицание числа без знака вычисляется путем вычитания его значения из 2ⁿ, где n - числобиты в продвинутом операнде.
Итак, чтобы узнать значение -0x80000000u
, нам нужно знать n
, количество бит в типе 0x80000000u
.Это как минимум 32, но это все, что мы знаем (без дополнительной информации о размерах типов в вашей реализации).Учитывая некоторые значения n
, мы можем вычислить, каков будет результат:
n | -0x80000000u
----+--------------
32 | 0x80000000
33 | 0x180000000
34 | 0x380000000
48 | 0xFFFF80000000
64 | 0xFFFFFFFF80000000
(Например, реализация, в которой unsigned int
равен 16 битам, а unsigned long
равен 64 битам, будет иметь n
из 64).
C99 имеет эквивалентную формулировку, скрытую в §6.2.5 Типы p9:
Вычисление, включающее операнды без знака, никогда не может быть переполнено, потому что результаткоторый не может быть представлен результирующим целочисленным типом без знака, уменьшается по модулю на число, которое на единицу больше наибольшего значения, которое может быть представлено результирующим типом.
Результат унарного оператора -
для беззнакового операнда, отличного от нуля, это правило всегда будет отслеживаться.
При 32-битном int
тип 0x80000000
будет unsigned int
, независимо от отсутствия u
суффикс, поэтому результатом все равно будет значение 0x80000000
с типом unsigned int
.
Если вместо этого вы используете десятичную константу 2147483648
, она будет иметь тип long
, и вычисление будет подписано.Результатом будет значение -2147483648
с типом long
.