С Новым годом! Форум программистов, компьютерный форум, киберфорум
Наши страницы

С++ для начинающих

Войти
Регистрация
Восстановить пароль
 
BESSON_off
3 / 0 / 1
Регистрация: 08.07.2013
Сообщений: 351
#1

Операции сдвига - C++

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

Через операторы сдвига можно в одну переменную поместить несколько значений.
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
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
24.11.2014, 13:51
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Операции сдвига (C++):

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

операции сдвига - C++
помогите со сдвигом требуется сделать в цикле сдвиг нуля в такой последовательности. подскажите как сделать? 11111110 11111101 ...

Побитовые операции сдвига - C++
Как работают операции сдвига вправо? Я всегда считал что освобождающиеся левые биты заполняются нулями. Оказывается это не всегда так. Если...

Операции сдвига в языке C. - C++
Нужно сформировать шестнадцатеричное число с помощью операций сдвига. Помогите продолжить программу. #include &lt;stdio.h&gt; int main()...

Упаковка пакета с помощью операции сдвига - C++
здравствуйте подскажите пожалуйста, правильно ли написано по этой картинке unsigned_int16 a,b; packet = a &lt;&lt;8; packet = a&lt;&lt;5...

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

8
Kuzia domovenok
2078 / 1907 / 176
Регистрация: 25.03.2012
Сообщений: 6,574
Записей в блоге: 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
BESSON_off
3 / 0 / 1
Регистрация: 08.07.2013
Сообщений: 351
25.11.2014, 05:23  [ТС] #3
Про битовые поля то я слышал, просто макрос RGB привел к тому, что пришлось задуматься, как можно реализовать обратный манёвр.
0
TheCalligrapher
С чаем беда...
Эксперт CЭксперт С++
3969 / 2193 / 553
Регистрация: 18.10.2014
Сообщений: 3,803
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
BESSON_off
3 / 0 / 1
Регистрация: 08.07.2013
Сообщений: 351
26.11.2014, 05:40  [ТС] #5
Цитата Сообщение от TheCalligrapher Посмотреть сообщение
Во-вторых, непонятно, почему 'b[1]' использовано два раза, а 'b[0]' - ни разу.
Торопился вопрос задать.
За ответ спасибо!
0
ValeryS
Модератор
6729 / 5138 / 485
Регистрация: 14.02.2011
Сообщений: 17,254
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
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
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
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
26.11.2014, 07:06 #8
Двоичная маска не вся вошла, вот её скрин из экзела:
Операции сдвига
.
0
taras atavin
3570 / 1754 / 91
Регистрация: 24.11.2009
Сообщений: 27,567
26.11.2014, 07:09 #9
Цитата Сообщение от ValeryS Посмотреть сообщение
&0xFF можно не делать, само сделается из-за разной размерности типов
В принципе да. Когда приводишь к типу, имеющему ту же разрядность, что и помещаемое в него значение, то маска не обязательна.
0
26.11.2014, 07:09
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
26.11.2014, 07:09
Привет! Вот еще темы с ответами:

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

Битовые операции и операции смещения языка С - C++
Доброго времени суток господа,помогите пожалуйста.Есть 2 кода к задаче,первый работает верно(переводит обычные числа в 16-ти ричные),а...

Заменить операции ifstream на операции fprintf - C++
Собственно как и написано в заголовке заменить операции ifstream на fprintf со всеми вытекающими(типо getline) необходимо мне. Помогите...

операция сдвига - C++
Объясните пожалуйста как именно работает и для чего нужна операция сдвига влево, в выражении например: N = 10; r = 1 &lt;&lt; N; И если...


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

Или воспользуйтесь поиском по форуму:
9
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2017, vBulletin Solutions, Inc.