Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
Карта форума Темы раздела Блоги Сообщество Поиск Заказать работу  
 
Рейтинг 4.75/8: Рейтинг темы: голосов - 8, средняя оценка - 4.75
3 / 0 / 0
Регистрация: 08.07.2013
Сообщений: 351
1

Операции сдвига

24.11.2014, 13:51. Показов 1566. Ответов 8
Метки нет (Все метки)

Author24 — интернет-сервис помощи студентам
Через операторы сдвига можно в одну переменную поместить несколько значений.
C++
1
2
3
4
5
6
int A = 0;
int b[3] = {44,45,46};
A = (int)(b[1]|b[2]<<4|b[1]<<8);
for (int i=0;i<3;i++) {
    b[i] = 0;
}
А как вытащить обратно эти значения в переменные b?
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
24.11.2014, 13:51
Ответы с готовыми решениями:

Операции сдвига
Помогите понять операции сдвига. Вот два примера левого и правого сдвига. 9 (base 10):...

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

Побитовые операции сдвига
Как работают операции сдвига вправо? Я всегда считал что освобождающиеся левые биты заполняются...

Операции сдвига в языке C.
Нужно сформировать шестнадцатеричное число с помощью операций сдвига. Помогите продолжить...

8
4064 / 3318 / 924
Регистрация: 25.03.2012
Сообщений: 12,495
Записей в блоге: 1
24.11.2014, 14:03 2
Регистрация: 08.07.2013
Сообщений: 265
и до сих пор не разобрался со сдвигом?

Цитата Сообщение от BESSON_off Посмотреть сообщение
можно в одну переменную поместить несколько значений
А про битовые поля ты что-нибудь слышал?
C
1
2
3
4
5
struct multiBit{
  unsigned a:4;//4х битное поле
  unsigned b:3;//3х битное поле  
  unsigned c:1;//1х битное поле  
};
А про юнионы?
C
1
2
3
4
5
6
7
8
9
union multiValue{
  struct{
    unsigned char a;//1й байт
    unsigned char b;//2й байт
    unsigned char c;//3й байт
    unsigned char d;//4й байт
  }bytes;
  int value;  
};
А теперь то и другое вместе?
C
1
2
3
4
5
6
7
8
union multiBitValue{
  struct{
  unsigned a:4;//4х битное поле
  unsigned b:3;//3х битное поле  
  unsigned c:1;//1х битное поле  
  }bytes;
  int value;  
};
...правда, тут ещё выравнивание желательно через #pragma pack сделать...
0
3 / 0 / 0
Регистрация: 08.07.2013
Сообщений: 351
25.11.2014, 05:23  [ТС] 3
Про битовые поля то я слышал, просто макрос RGB привел к тому, что пришлось задуматься, как можно реализовать обратный манёвр.
0
Вездепух
Эксперт CЭксперт С++
11696 / 6375 / 1724
Регистрация: 18.10.2014
Сообщений: 16,077
25.11.2014, 06:08 4
Цитата Сообщение от BESSON_off Посмотреть сообщение
A = (int)(b[1]|b[2]<<4|b[1]<<8);
Во-первых, битовые операции лучше производить над беззнаковыми типами.

Во-вторых, непонятно, почему 'b[1]' использовано два раза, а 'b[0]' - ни разу.

Цитата Сообщение от BESSON_off Посмотреть сообщение
как можно реализовать обратный манёвр
Если

C++
1
A =  b[0] | b[1] << 4 | b[2] << 8;
то

C++
1
2
3
b[0] = A & 0xF; 
b[1] = A >> 4 & 0xF; 
b[2] = A >> 8 & 0xF;
или

C++
1
2
3
b[0] = A & 0xF; A >>= 4;
b[1] = A & 0xF; A >>= 4;
b[2] = A & 0xF; A >>= 4;
1
3 / 0 / 0
Регистрация: 08.07.2013
Сообщений: 351
26.11.2014, 05:40  [ТС] 5
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Во-вторых, непонятно, почему 'b[1]' использовано два раза, а 'b[0]' - ни разу.
Торопился вопрос задать.
За ответ спасибо!
0
Модератор
Эксперт по электронике
8909 / 6678 / 918
Регистрация: 14.02.2011
Сообщений: 23,523
26.11.2014, 06:35 6
Цитата Сообщение от BESSON_off Посмотреть сообщение
A = (int)(b[1]|b[2]<<4|b[1]<<8);
Цитата Сообщение от BESSON_off Посмотреть сообщение
просто макрос RGB привел к тому, что пришлось задуматься,
а ты уверен что привел макрос RGB?
Там байты используются
соответственно
C++
1
2
3
4
5
unsigned int color=(unsigned int)(R|G<<8|B<<16);
 
unsigned char R= color&0xFF;
unsigned char G= (color>>8)&0xFF;
unsigned char B= (color>>16)&0xFF;
&0xFF можно не делать, само сделается из-за разной размерности типов
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.11.2014, 07:03 7
Kuzia domovenok, при чём здесь это? Он сдвигами хотел.BESSON_off, когда ты помещаешь значения в переменную сдвигом, то каждое помещаешь на какие то биты. На какие? Предположим, ты собрал двойное слово из байтов:
C++
1
b=((DWORD)x1)|(((DWORD)x2)<<8)|(((DWORD)x3)<<16)|(((DWORD)x4)<<24);
, а потом хочешь вытащить эти байты. На каких битах они находятся? x1 от нулевого до седьмого, так как всего бит в байте 8, а младший бит всегда и везде нулевой. Младший бит значения нулевой, младший бит значения, упакованного в переменную нулевой, позиция одна, двигать не надо, только маска:
C++
1
x=(char)(b&0x000000FF);
. x2 от 8-го до 15-го, а надо от нулевого до седьмого, разница 8. Обратил внимание на то, что она совпадает с величиной сдвига при помещении? Это не случайно. Значит двигать надо в обратную сторону на те же 8, но помещение мог реализовать кто то другой, а тебе сказать только номера бит, тогда считай разность, она равна меньшему номеру (вычитание ноля даёт разность, равную уменьшаемому).
C++
1
x2=(char)((b&0x0000FF00)>>8);
. x3 от 16-го до 23-го, разность 16,
C++
1
x3=(char)((b&0x00FF0000)>>16);
. x4 от 24-го до 31-го, разность 24.
C++
1
x4=(char)((b&0xFF000000)>>16);
. 0x000000FF, 0x0000FF00, 0x00FF0000 и 0xFF000000 - это маски значений. Как их определять? Есть номера битов, которые тебе нужны, пиши двоичное число, в котором биты с этими номерами равны 1, остальные 0, например, 00000000000000001111111100000000 для битов от 8-го до 15-го. Почему именно здесь единицы? Потому что биты нумеруются слева на право с ноля с увеличением на 1:
биты:000000000000000011111110
номера битов:3130292827262524232221201918171615141312111098
. Видишь, где единицы? Теперь группируй биты по четыре:
полубайты:00000000000000001111111100000000
на каких они номерах битов:28-3124-2720-2316-1912-158-114-70-3
. Полученные полубайты заменяй на шестнадцатеричные цифры (такая цифра - это тоже полубайт, но в другой системе счисления) по таблице:
двоичный полубайтшестнадцатеричный полубайт
00000
00011
00102
00113
01004
01015
01106
01117
10008
10019
1010A
1011B
1100C
1101D
1110E
1111F
, получается 0000FF00, теперь в начало пиши 0x. Всё, маска готова. При помещении тоже может понадобиться маска, если исходные значения были представлены типами большей разрядности, чем нужно. Какие биты они на самом деле имеют? Составляй маску по аналогии, например, если ты собираещь двойное слово из ASCII, то маска значения 0x7F, при расширении до двойного слова она становится 0x0000007F, тогда
C++
1
b=(((DWORD)x1)&0x0000007F)|((((DWORD)x2)&0x0000007F)<<7)|((((DWORD)x3)&0x0000007F)<<14)|((((DWORD)x4)&0x0000007F)<<21);
, а маски при выделении значений 0x0000007F, 0x00003F80, 0x001FC000 и 0x0FE00000.
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.11.2014, 07:06 8
Двоичная маска не вся вошла, вот её скрин из экзела:
Операции сдвига

.
0
4226 / 1795 / 211
Регистрация: 24.11.2009
Сообщений: 27,562
26.11.2014, 07:09 9
Цитата Сообщение от ValeryS Посмотреть сообщение
&0xFF можно не делать, само сделается из-за разной размерности типов
В принципе да. Когда приводишь к типу, имеющему ту же разрядность, что и помещаемое в него значение, то маска не обязательна.
0
26.11.2014, 07:09
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.11.2014, 07:09
Помогаю со студенческими работами здесь

Упаковка пакета с помощью операции сдвига
здравствуйте подскажите пожалуйста, правильно ли написано по этой картинке unsigned_int16...

Операции сдвига, перегруженые функции. Объясните суть
Люди, помогите плиз. Дали на летнюю практику задания, которые в семестре не делали впринципе(учили...

Перегрузить операции сравнения комплексных чисел и операции потокового вывода
Создать класс комплексное число. Перегрузить операции сравнения комплексных чисел! =, ==,&gt;, &lt;,&gt; =,...

Заменить операции ifstream на операции fprintf
Собственно как и написано в заголовке заменить операции ifstream на fprintf со всеми...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2024, CyberForum.ru