1000 0000, что равно -0 ...
Единичное дополнение имеет -0, но большинство компьютеров используют два дополнения , чего нет.
В обозначении два дополнения крайний левый бит представляет -(coefficient_bit * 2^N-1)
, т.е. в вашем случае 1000 0000
крайний левый бит представляет -(1 * 2^8-1)
, что является равно -128
, и поэтому результат такой же.
Ваш char
- это 8-битное целое число со знаком, и в этом случае 1000 0000 равно -128. Мы можем проверить, что такое 1000 0000, удобно с помощью расширения GNU, которое допускает двоичные константы .
char a = 0b10000000;
printf("%d\n", a); // -128
char
в этой реализации является 8-битным целым числом со знаком. Добавление 1 к 127 приводит к переполнению целого числа до -128.
А как насчет целочисленного продвижения? Целочисленное продвижение происходит во время вычисления, но результат по-прежнему char
. 128 не может поместиться в наш подписанный 8-битный char, поэтому он переполняется до -128.
Целочисленное продвижение демонстрируется в этом примере .
char a = 30, b = 40;
char c = (a * b);
printf("%d\n", c); // -80
char d = (a * b) / 10;
printf("%d\n", d); // 120
char c = (a * b);
равно -80, а char d = (a * b) / 10;
120. Почему? Разве не должно быть -8? Ответ здесь - это целочисленное продвижение. Вычисления выполняются как собственные целые числа, но результат все равно должен быть помещен в 8-битный символ. (30 * 40)
- 1200, что составляет 0100 1011 0000. Затем его нужно вставить обратно в 8-битовое целое число со знаком; это 1011 0000 или -80.
Для других расчетов (30 * 40) / 10
== 1200 / 10
== 120, что идеально подходит.