Подписанные целые числа представлены на x86 через два дополнения, где знаковый бит имеет значение -(2^N)
. Это приводит к типичному представляемому диапазону значений между -2^N
и 2^N - 1
(например, -32768
- 32767
).INT_MIN * -1 a-no-op на x86?
Мне было любопытно, что произойдет, если я возьму минимальное знаковое целочисленное значение в своей системе и умножьте его на -1
, пытаясь «заставить» максимальное значение, большее, чем максимальное представляемое значение целых чисел со знаком в моей системе.
#include <stdio.h>
#include <limits.h>
int main(void){
signed int x, y;
x = INT_MIN;
y = x * -1;
printf("%d\n%d\n", x, y);
return 0;
}
Это привело к следующему выходу:
# gcc -std=c89 -pedantic int_min_test.c
# ./a.out
-2147483648
-2147483648
Я ожидал целочисленное переполнение (в результате типичного значения опрокидывание), но это, кажется, как будто никакой операции не произошло относительно умножения x
с -1
.
Является ли умножение INT_MIN
на -1
a no-op in x86?
Не будет ли опрокидывание точно производить наименьшее возможное значение снова? –
Это неопределенное поведение (для дополнения 2) - не имеет ничего общего с x86. –
Что сказал @KerrekSB. Если вы хотите наблюдать это без UB, используйте только неподписанные типы. –