Страница 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, то предпоследний (xxxxxx
Xx) бит окажется промежуточным буфером.
Разложим:
1. Делаем сдвиг
2 Сравниваем 0 бит с нулём.
3. Если не ноль, устанавливаем 5 бит
4. Если ноль - не делаем ничего.
Так вот, на третьем шаге у вас и в нулевом бите будет единица, и в пятом.
PS. если крутить старшие, тогда так:
(a>>1) | (a&4 ? 0x80 : 0);
Нене, получится то, что я выше написал
На следующем шаге мы просто заберём из xxxxxx
Xx этого бита (который не виден на выходе) значение и вставим в старший. А вы хотите из xxxxx
Xxx этого, который участвует в процессе.
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 (не меняет ее), а дает на выходе результат сдвигания переменной.
Конечно же! Мой косяк. Хватит на сегодня работать.
... налил себе кофе и достал правильный бутерброд