гибкая разработка программного обеспечения Alistair Cockburn
Когда старший бит равен нулю, число положительное. Когда оно равно 1, число отрицательное.
Отрицательные числа, сдвинутые вправо, продолжают сдвигать «1» в качестве самого верхнего бита, чтобы число оставалось отрицательным. Вот почему вы получаете этот ответ.
Чтобы узнать больше о двух дополнениях, см. этот вопрос Stackoverflow .
@Stobor указывает, что некоторые реализации C могут сдвигать 0 в старший бит вместо 1 . [Проверено в Википедии.] В Java это надежный арифметический сдвиг.
Но вывод, данный вопрошающим, показывает, что его компилятор выполняет арифметический сдвиг.
Стандарт C не определяет, сдвигает ли сдвиг вправо отрицательного (обязательно со знаком) целого числа нули (логический сдвиг вправо) или знаковые биты (арифметический сдвиг вправо) в самый старший бит. Выбор зависит от реализации.
Следовательно, переносимый код гарантирует, что он не выполняет сдвиги вправо для отрицательных чисел.
Это операция арифметического сдвига, которая сохраняет знаковый бит и сдвигает мантиссу числа со знаком.
приветствует
Обычно существует два типа сдвига вправо. Беззнаковый сдвиг вправо и знаковый сдвиг вправо. Беззнаковый сдвиг вправо сдвинет биты вправо, в результате чего наименее значащий бит будет потерян, а старший значащий бит будет заменен на 0. При сдвиге вправо со знаком биты сдвигаются вправо, вызывая наименьшее значение. старший бит должен быть потерян, а старший значащий бит сохранен. Знаковый сдвиг вправо делит число на степень двойки (соответствует количеству сдвинутых разрядов), тогда как сдвиг без знака является логической операцией сдвига.
Оператор «>>» выполняет сдвиг вправо без знака, когда тип данных с которым он работает, беззнаковый, и он выполняет сдвиг вправо со знаком, когда тип данных, с которым он работает, подписан. Так,
Взгляните на описание дополнения до двух . Это должно помочь.
РЕДАКТИРОВАТЬ: Когда было написано ниже, код в вопросе был записан как:
unsigned int a = -1;
printf(("The number is %d ",(a>>31));//this prints as -1
Если unsigned int имеет ширину не менее 32 бита, то ваш компилятор не 'На самом деле не разрешено производить -1 в качестве результата этого (с небольшой оговоркой, что вы должны преобразовать беззнаковое значение в int, прежде чем передавать его в printf).
Поскольку a является беззнаковым int, присваивая -1 для он должен дать ему значение UINT_MAX (как наименьшее неотрицательное значение, конгруэнтное -1 по модулю UINT_MAX + 1). Пока unsigned int имеет на вашей платформе как минимум 32 бита, результатом сдвига этого беззнакового количества вправо на 31 будет UINT_MAX, деленное на 2 ^ 31, что должно соответствовать int. (Если длина unsigned int 31 бит или меньше, она может производить все, что угодно, потому что результат сдвига не указан).