Страница 1 из 1

битовый сдвиг числа

Добавлено: Ср авг 21, 2013 13:15:26
yurik7272
Добрый день! Подскажите пожалуйста, как на С организовать циклический побитовый сдвиг числа типа unsigned char, но чтобы сдвиг происходил в пределах 6 бит. То есть нужно получить такую последовательность: 111000, 011100, 001110, 000111, 100011, 110001 и так далее по кругу

Re: битовый сдвиг числа

Добавлено: Ср авг 21, 2013 13:30:22
a_skr
если точно знаем, что в старших 2-х нули, то можно так:
a = (a>>1) | (a&1 ? 0x20 : 0);

Re: битовый сдвиг числа

Добавлено: Ср авг 21, 2013 13:39:27
ploop
Тогда a = (a>>1) | (a&1 ? 0x80 : 0);
Мы старший бит опять устанавливаем.

Re: битовый сдвиг числа

Добавлено: Ср авг 21, 2013 13:42:23
a_skr
6 бит всего

Re: битовый сдвиг числа

Добавлено: Ср авг 21, 2013 13:45:35
ploop
Он не уточнил, двигать надо старшие или младшие 6 бит.
Вы сравниваете первый бит с нулём, в которой переедет младший из 6 старших бит после сдвига. Поэтому я предположил, что двигаем старшие. Значит и устанавливать надо старший бит, если первый бит не ноль.

Уфф :)

Re: битовый сдвиг числа

Добавлено: Ср авг 21, 2013 13:50:24
ploop
А, нет, там единица, а не первый бит :)
Короче младшие двигать не получится без промежуточной переменной. Только так:
(a>>1) | (a&2 ? 0x80 : 0);

Re: битовый сдвиг числа

Добавлено: Ср авг 21, 2013 13:53:01
a_skr
я сравниваю младший из 8-ми с единицей, тем более предположил, что крутим младшие 6, а
если точно знаем, что в старших 2-х нули
и помещаю его в 6-й (если считать с единицы) ;)

PS. если крутить старшие, тогда так:
(a>>1) | (a&4 ? 0x80 : 0);

Re: битовый сдвиг числа

Добавлено: Ср авг 21, 2013 14:00:44
ploop
У вас таким образом младший из 6 (и из 8 ) тут же перейдёт в старший из 6. То есть останется и в старшем и в младшем.
А если крутить старшие 6 из 8, то предпоследний (xxxxxxXx) бит окажется промежуточным буфером.

Разложим:
1. Делаем сдвиг
2 Сравниваем 0 бит с нулём.
3. Если не ноль, устанавливаем 5 бит
4. Если ноль - не делаем ничего.

Так вот, на третьем шаге у вас и в нулевом бите будет единица, и в пятом.

PS. если крутить старшие, тогда так:
(a>>1) | (a&4 ? 0x80 : 0);

Нене, получится то, что я выше написал :)
На следующем шаге мы просто заберём из xxxxxxXx этого бита (который не виден на выходе) значение и вставим в старший. А вы хотите из xxxxxXxx этого, который участвует в процессе.

Re: битовый сдвиг числа

Добавлено: Ср авг 21, 2013 14:03:07
yurik7272
Большое спасибо, всё получилось!

Re: битовый сдвиг числа

Добавлено: Ср авг 21, 2013 14:08:04
a_skr
короче, вопрос к ТС: какие биты из 8-ми крутить и что делать с остальными 2-мя?

1. самый простой вариант: 00ХХХХХХ - см. мой первый ответ:
a = (a>>1) | (a&1 ? 0x20 : 0);

2. УУХХХХХХ (УУ не меняем):
a = (a&0xC0) | ((a>>1)&0x1F) | (a&1 ? 0x20 : 0);

3. ХХХХХХУУ (УУ не меняем):
a = ((a>>1)&0xEC) | (a&4 ? 0x80 : 0) | (a&0x03);

справедливо и для signed char

PS. ploop, предлагаю Вам промоделировать и показать мне результат работы программы, где я не прав. а то словами можно долго описывать и пытаться понять друг друга ;)

PPS.
Разложим:
1. Делаем сдвиг

a>>1 - ничего не делает с переменной a (не меняет ее), а дает на выходе результат сдвигания переменной.

Re: битовый сдвиг числа

Добавлено: Ср авг 21, 2013 14:33:25
ploop
a>>1 - ничего не делает с переменной a (не меняет ее), а дает на выходе результат сдвигания переменной.

Конечно же! Мой косяк. Хватит на сегодня работать.

... налил себе кофе и достал правильный бутерброд