2015-05-21 3 views
0

Можно ли сдвинуть 0 s, поскольку вы можете сдвинуть 1 s в операции переключения в C?Операция сдвига в C

Что-то вроде этого

for (i=0; i<32; i++) { 
    if (data & 0x01) { 
     data |= (1<<i); 
    } 
    else { 
     data &=~ (0<<i); 
    } 
} 

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

+2

Сдвиг «сдвига» как нули и единицы. –

+2

Прежде всего, оператор '<' является оператором меньше, чем сравнение. Во-вторых, если вы хотите * очистить * биты, используйте побитовые операторы AND ('&') и дополнения ('' '). –

+0

зачем снимать? Я просто маскирую (проверяю) необходимые биты и сохраняю их в новой переменной с помощью оператора сдвига – Lazar

ответ

0

Операции сдвига выполняются с использованием регистра центрального процессора. Регистр состоит из нескольких бит (8, 16 и 32 являются общими, и у вас есть 32 CPU), которые в комбинации можно интерпретировать как десятичное значение.

В вашем примере используется значение 1. Язык C позволяет ценностному быть представлены несколькими способами, все из которых приводят к тем же содержанием регистра процессора:

decimal  hexadecimal binary 
1   0x00000001 0b00000000000000000000000000000001 
3713883835 0xDD5D5EBB 0b11011101010111010101111010111011 

(Во всех делающие ведущие 0 s могут быть опущены.)

В двоичном представлении указываются все значения битов регистра CPU. Как вы можете видеть, это включает 0 и 1 сек. Поэтому, когда вы поместите значение 1 в регистр и выполните сдвиг влево с помощью оператора <<, содержимое всего регистра будет сдвинуто налево на один бит, а 0 будет помещено в младший значащий бит.

В своем коде значение, присвоенное данным будет следовать этой схеме:

i = 0, data = 0x00000000000000000000000000000001 
i = 1, data = 0x00000000000000000000000000000010 
i = 2, data = 0x00000000000000000000000000000100 
etc. 
i = 30, data = 0x01000000000000000000000000000000 
i = 31, data = 0x10000000000000000000000000000000 

Если вы использовали другое значение, чем 1 сдвиг, вы бы, конечно, в конечном итоге с другим рисунком, но это будет следовать тем же правилам. То есть все биты сдвигаются, независимо от того, имеют ли они 1 или 0.

for(i=0;i<32;i++) 
{ 
    data = (165 << i) // 165 = 0xA5 = 0b10100101 
} 

Produces: 
i = 0, data = 0x00000000000000000000000010100101 
i = 1, data = 0x00000000000000000000000101001010 
i = 2, data = 0x00000000000000000000001010010100 
etc. 
i = 28, data = 0x10100000000000000000000000000000 
i = 29, data = 0x01000000000000000000000000000000 
i = 30, data = 0x10000000000000000000000000000000 
i = 31, data = 0x00000000000000000000000000000000 

Обратите внимание, как картина исчезает к концу, как самые старшие биты сдвигаются из регистра.

Те же правила справедливы для выполнения сдвигов вправо с использованием оператора >>, за исключением того, что бит перемещается от наиболее значимого к наименее значащему.

(Некоторые процессоры также Rotate и другие замечательные инструкции немного манипуляции.)

3

Вы не сдвигаются 0 или 1, вы переносите битовые значения, будь то либо 0 или 1. Другими словами, вы сдвигаете позиции бит, независимо от значения , хранящегося в них.

От C11 стандарт, глава §6.5.7. , Битовые операторы сдвига

Результат E1 << E2 является E1 сдвинуты влево E2 битовые позиции; освобожденные биты заполняются нулями.

Это просто, как, что, в случае 1 с, перенесение является видимым.

Это говорит, <является не оператор битового сдвига (как в коде), << есть.

+0

Если я сменю переменную, он сохранит эту ценность в будущих операциях? – Lazar

+0

@ Lazar, что это за работа в будущем? См., '' '' Производит _shifted value_. Если вы хотите сохранить значение, вы должны вернуть значение _shifted_ самой переменной. Точно так же, как 'i + 1' не изменяет' i', но 'i = i + 1' делает. –

+0

Итак, чтобы получить новое значение переменной, нам нужно назначить это значение в новой или существующей переменной, в которой применяется операция.Когда переменные In/decmenting или shifting, значение переменной не изменяется до тех пор, пока оно не будет присвоено самому себе, как вы сказали для i. – Lazar

2

<< (не <!) Не меняется один бит. Он сдвигает все число. Когда вы говорите 1<<5, он сдвигает 0000000000000001 на пять мест (учитывая 16-битное значение), которое дает 0000000000100000. 0<<5 смещается 0000000000000000 пять мест слева, что приводит к 0000000000000000 (т. Е. Такое же значение). Другие биты не являются неопределенными: вы не можете сдвинуть один бит (я предполагаю, что вы хотите что-то вроде ??????????1????? и ??????????0?????, но номера не работают так.)

Это похоже на типичную проблему XY. Вероятно, вы хотите использовать data, чтобы включить или выключить бит в чем-то еще? Задать вопрос о , что. (EDIT: Как сказал Йоахим Пилеборг в комментариях.)

1

Хорошей новостью является то, что вы передумали.

Возьмите все число, скажем: 01011011.

Сдвинуть влево 1: 10110110.

«Все это» сдвигается вместе; нули сдвинуты в LSB. В случае сдвига вправо он снова равен нулю для неподписанных или определенных для подписанных номеров значений:

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

(S6.5.7)

Что означает сдвига вправо подписанный номер может привести либо к арифметический сдвиг или логический сдвиг.


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

Смежные вопросы