Подтвердить что ты не робот

Можете ли вы контролировать, какой побитный сдвиг вправо будет заполняться C?

Насколько я знаю, когда вы используете побитовый оператор с левым сдвигом в C, он гарантирует, что свободные бит будут заполнены 0s. Тем не менее, я читал, что правильный сдвиг зависит от реализации, то есть в некоторых машинах свободные разряды будут заполняться 0, а в других они будут заполнены 1 сек.

Я использую правый сдвиг в программе, и, действительно, моя машина заполняет свободные бит 1 сек. Проблема в том, что мне нужно будет заполнить 0s вместо.

Есть ли способ заставить 0s использоваться в сдвигах вправо?

Одним из решений было бы, после применения правого сдвига, создать маску типа 011111111, а затем применить побитовое И, которое изменит самый левый 1, который был вставлен в 0.

Но это громоздко и тратит время. Если бы был способ сообщить моей машине, чтобы заполнить правые смены с помощью 1 с, было бы намного проще.

Спасибо

4b9b3361

Ответ 1

Введите число до unsigned и затем сдвиньте. Это заставит 0-заполнять.

Ответ 2

Нет, вы не можете.

Сдвиги по неподписанным типам четко определены (если правый операнд неотрицателен и меньше ширины левого операнда), и они всегда заполняют нуль.

Сдвиги (или любые побитовые операции) на подписанных типах обычно не являются хорошей идеей. Если левый операнд отрицательный, то << имеет поведение undefined, а >> дает результат, определенный реализацией (это означает, что компилятор должен документировать, что он делает, но нет способа контролировать его). Для неотрицательных значений подписанного типа результат - это то, что вы ожидаете - до тех пор, пока он не переполняется (если он переполняется, поведение undefined).

Вот что говорит C99 стандарт (раздел 6.5.7):

Целочисленные рекламные акции выполняются для каждого из операндов. Тип Результатом является результат продвинутого левого операнда. Если значение правый операнд отрицательный или больше или равен ширине продвинутого левого операнда, поведение undefined.

Результат E1 < < E2 E1 бит слева E2позиции; освобожденные биты заполняются нулями. Если E1 имеет неподписанное type, значение результата E1 × 2 E2 уменьшено по модулю еще один чем максимальное значение, представляемое в типе результата. Если E1 имеет подписанный тип и неотрицательное значение, а E1 × 2 E2 представим в тип результата, то это результирующее значение; в противном случае поведение undefined.

Результат E1 E2 - это E1 смещенные по вертикали позиции E2. Если E1unsigned type или если E1 имеет подписанный тип и неотрицательное значение, значение результата является неотъемлемой частью частного E1/ 2 E2. Если E1 имеет подписанный тип и отрицательное значение, результат значение определяется реализацией.

Ответ 3

Существует два разных режима сдвига справа: арифметические и логические.

Логический сдвиг используется с неподписанными числами в C. Он всегда заполняет старшие биты нулями. Это то, что вам нужно.

Арифметический сдвиг используется с подписанными числами, поскольку он сохраняет знак смещения числа. Если число положительное, самый старший бит будет 0, и он будет заполняться 0 с. Если число отрицательное, наиболее значимый бит будет равен 1, поэтому он будет заполняться 1 с.

Обратите внимание, что в Java они фактически используют разные операторы: >> для арифметики, >>> для логического. Это необходимо, потому что Java не имеет неподписанного типа.