3 / 3 / 3
Регистрация: 23.06.2015
Сообщений: 38
1

Где и когда уместно применять операции << (сдвиг влево) и >> (сдвиг вправо)?

02.08.2016, 17:10. Показов 3983. Ответов 15
Метки нет (Все метки)

Кто может привести пример , когда нужно использовать операции:
1) << сдвиг влево
2) >> сдвиг вправо
__________________
Помощь в написании контрольных, курсовых и дипломных работ, диссертаций здесь
0
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
02.08.2016, 17:10
Ответы с готовыми решениями:

Культура оформления кода: что такое enum? Где, когда и для чего уместно применять этот тип?
не понял за что отвечают эти две строчки: enum ChosenOperation { ADD = 1, SHOW, SEARCH, EXIT };...

Побитовый сдвиг влево и вправо
Что выполнится быстрее - сдвиг влево или сдвиг вправо? И как замерить время выполнения каждой из...

Циклический сдвиг массива влево и вправо
Нужно реализовать циклический сдвиг массива влево и вправо! Например есть массив int- {121605}?...

Осуществить сдвиг влево/ вправо элементов
Разработать подпрограммы (функции или процедуры) для следующих алгоритмов над массивом. Входным...

15
Заблокирован
02.08.2016, 17:24 2
установить 4-й бит в 1, тогда 1<<4, а иначе искать 24 и 1*16
0
19 / 29 / 13
Регистрация: 09.02.2016
Сообщений: 230
02.08.2016, 22:02 3
при умножении и делении на 2
C++
1
2
int x=5;
x<<=n;
оно же x = x * 2ⁿ
0
331 / 283 / 78
Регистрация: 02.08.2016
Сообщений: 1,008
02.08.2016, 22:21 4
Сдвиг влево передвигает все биты числа влево, т.е. умножает на 2. Вправо, соответственно, делит. Из практических примеров:
C++
1
2
int value = 1 << 5;// установить 5ый бит в 1, а все остальные в 0
value |= 1 << 2;// установить 2ой бит в 1, остальные не трогать
0
4811 / 2271 / 287
Регистрация: 01.03.2013
Сообщений: 5,933
Записей в блоге: 26
02.08.2016, 23:21 5
Когда битовая маска набирается из отдельных бит, каждый из которых отвечает за какой-то флаг, то сплошь и рядом в сях и ассемблерах пишут:
C
1
x = 1<<BIT1 || 1<<BIT2 || 1<<BIT3
Но местные ООП-гуру презрительно называют это термином бито...тво.
0
2548 / 1207 / 358
Регистрация: 30.11.2013
Сообщений: 3,826
02.08.2016, 23:40 6
Заниматься бито..твом, когда на компьютерах i3-ие процессоры и по 8ГБ ОЗУ....
1
858 / 447 / 112
Регистрация: 06.07.2013
Сообщений: 1,494
03.08.2016, 17:47 7
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Заниматься бито..твом, когда на компьютерах i3-ие процессоры и по 8ГБ ОЗУ
для вычисления коллизий по битовой маске все таки еще можно использовать

Цитата Сообщение от sham63 Посмотреть сообщение
Кто может привести пример , когда нужно использовать операции:
установка флагов например, точнее их инициализация;
C++
1
2
3
4
const unsigned int FLAG_0 = 1 << 0;
const unsigned int FLAG_1 = 1 << 1;
const unsigned int FLAG_2 = 1 << 2;
...
0
Don't worry, be happy
17686 / 10433 / 2015
Регистрация: 27.09.2012
Сообщений: 26,282
Записей в блоге: 1
04.08.2016, 01:01 8
Цитата Сообщение от _Ivana Посмотреть сообщение
Но местные ООП-гуру
и используют bitset?
0
4811 / 2271 / 287
Регистрация: 01.03.2013
Сообщений: 5,933
Записей в блоге: 26
04.08.2016, 01:04 9
Croessmah, возможно Я не знаю - я не гуру, я использую как привел пример
0
Don't worry, be happy
17686 / 10433 / 2015
Регистрация: 27.09.2012
Сообщений: 26,282
Записей в блоге: 1
04.08.2016, 01:05 10
Цитата Сообщение от _Ivana Посмотреть сообщение
Я не знаю - я не гуру
значит ждем гуру, пусть поведает
0
4811 / 2271 / 287
Регистрация: 01.03.2013
Сообщений: 5,933
Записей в блоге: 26
04.08.2016, 01:08 11
Цитата Сообщение от Croessmah Посмотреть сообщение
значит ждем гуру, пусть поведает
- А можно я кузнецу врежу?!
- Нельзя, он у нас один!
...
0
3174 / 1933 / 313
Регистрация: 27.08.2010
Сообщений: 5,131
Записей в блоге: 1
04.08.2016, 07:11 12
Цитата Сообщение от sham63 Посмотреть сообщение
когда нужно использовать операции:
1) << сдвиг влево
2) >> сдвиг вправо
Почти всюду в низкоуровневых функциях: хэширование, шифрование, сжатие данных (т.е., практически вся мультимедия), математические библиотеки (a la FFT и прочее DSP), построение защит, оптимизация целочисленных вычислений итп.

из исходного кода AES

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
// Another implementation of the Rijndael cipher.
// This is intended to be an easily usable library file.
// This code is public domain.
// Based on the Vincent Rijmen and K.U.Leuven implementation 2.4.
 
int Rijndael::blockEncrypt(const BYTE *input,int inputLen,BYTE *outBuffer)
{
   int i, k, numBlocks;
   BYTE block[16], iv[4][4];
 
   if (m_state != Valid)return RIJNDAEL_NOT_INITIALIZED;
 
   if (m_direction != Encrypt)return RIJNDAEL_BAD_DIRECTION;
 
   if (!input || inputLen <= 0) return 0;
 
   numBlocks = inputLen/128;
   
   switch(m_mode){
      case ECB: 
         for (i = numBlocks;i > 0;i--)
         {
            encrypt(input,outBuffer);
            input += 16;
            outBuffer += 16;
         }
      break;
      case CBC:
         ((DWORD*)block)[0] = ((DWORD*)m_initVector)[0] ^ ((DWORD*)input)[0];
         ((DWORD*)block)[1] = ((DWORD*)m_initVector)[1] ^ ((DWORD*)input)[1];
         ((DWORD*)block)[2] = ((DWORD*)m_initVector)[2] ^ ((DWORD*)input)[2];
         ((DWORD*)block)[3] = ((DWORD*)m_initVector)[3] ^ ((DWORD*)input)[3];
         encrypt(block,outBuffer);
         input += 16;
         for (i = numBlocks - 1;i > 0;i--)
         {
            ((DWORD*)block)[0] = ((DWORD*)outBuffer)[0] ^ ((DWORD*)input)[0];
            ((DWORD*)block)[1] = ((DWORD*)outBuffer)[1] ^ ((DWORD*)input)[1];
            ((DWORD*)block)[2] = ((DWORD*)outBuffer)[2] ^ ((DWORD*)input)[2];
            ((DWORD*)block)[3] = ((DWORD*)outBuffer)[3] ^ ((DWORD*)input)[3];
            outBuffer += 16;
            encrypt(block,outBuffer);
            input += 16;
         }
      break;
      case CFB1:
#if STRICT_ALIGN 
         memcpy(iv,m_initVector,16); 
#else  /* !STRICT_ALIGN */
         *((DWORD*)iv[0]) = *((DWORD*)(m_initVector   ));
         *((DWORD*)iv[1]) = *((DWORD*)(m_initVector + 4));
         *((DWORD*)iv[2]) = *((DWORD*)(m_initVector + 8));
         *((DWORD*)iv[3]) = *((DWORD*)(m_initVector +12));
#endif /* ?STRICT_ALIGN */
 
         for (i = numBlocks; i > 0; i--)
         {
            for (k = 0; k < 128; k++)
            {
               *((DWORD*) block    ) = *((DWORD*)iv[0]);
               *((DWORD*)(block+ 4)) = *((DWORD*)iv[1]);
               *((DWORD*)(block+ 8)) = *((DWORD*)iv[2]);
               *((DWORD*)(block+12)) = *((DWORD*)iv[3]);
 
               encrypt(block,block);
               
               outBuffer[k/8] ^= (block[0] & 0x80) >> (k & 7);
 
               iv[0][0] = (iv[0][0] << 1) | (iv[0][1] >> 7);
               iv[0][1] = (iv[0][1] << 1) | (iv[0][2] >> 7);
               iv[0][2] = (iv[0][2] << 1) | (iv[0][3] >> 7);
               iv[0][3] = (iv[0][3] << 1) | (iv[1][0] >> 7);
               iv[1][0] = (iv[1][0] << 1) | (iv[1][1] >> 7);
               iv[1][1] = (iv[1][1] << 1) | (iv[1][2] >> 7);
               iv[1][2] = (iv[1][2] << 1) | (iv[1][3] >> 7);
               iv[1][3] = (iv[1][3] << 1) | (iv[2][0] >> 7);
               iv[2][0] = (iv[2][0] << 1) | (iv[2][1] >> 7);
               iv[2][1] = (iv[2][1] << 1) | (iv[2][2] >> 7);
               iv[2][2] = (iv[2][2] << 1) | (iv[2][3] >> 7);
               iv[2][3] = (iv[2][3] << 1) | (iv[3][0] >> 7);
               iv[3][0] = (iv[3][0] << 1) | (iv[3][1] >> 7);
               iv[3][1] = (iv[3][1] << 1) | (iv[3][2] >> 7);
               iv[3][2] = (iv[3][2] << 1) | (iv[3][3] >> 7);
               iv[3][3] = (iv[3][3] << 1) | (outBuffer[k/8] >> (7-(k&7))) & 1;
            }
         }
      break;
      default:
         return -1;
      break;
   }
   
   return 128 * numBlocks;
}
0
Одессит
242 / 87 / 44
Регистрация: 30.12.2013
Сообщений: 316
Записей в блоге: 2
04.08.2016, 12:26 13
Цитата Сообщение от rikimaru2013 Посмотреть сообщение
Заниматься бито..твом, когда на компьютерах i3-ие процессоры и по 8ГБ ОЗУ....
С такими рассуждениями, тогда лучше на джаве программировать, там логика - проще купить новую планку памяти, чем улучшить код.
Делал недавно проект для одной компании. Суть была в том, что есть некие приборы (железные ящики с 20-25 элементами управления (по-разному), у которых есть два значения вкл и вкл). Ящики стоят удалённо в глухомане и связь с оператором идёт через интернет gsm и не всегда стабильно. Так вот ящику нужно всего лишь передать одно целое число, где каждый бит будет означать соответствующий элемент и в зависимости от 1 или 0 - вкл или выкл.
0
183 / 181 / 66
Регистрация: 15.02.2015
Сообщений: 515
04.08.2016, 12:41 14
Надо было битовый массив, представленный как байтовый массив (27 бит - 4 байта, например), скопировать в другой битовый массив (поболее) начиная с заданной позиции, т.е. со смещением. Смещение кратно 8-ми - memcpy, иначе пляски со сдвигами, масками и побитовыми операциями.
Кликните здесь для просмотра всего текста
например
C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
enum {
    ...
    OCTET = 8,
    BYTE_MASK = 0xff
}
using Byte = uint8_t;
using Word = uint16_t;
...
Byte bits_array[(1 + UINT16_MAX)  / OCTET + 1];  //65536 бит + 1 байт для защиты выхода за границы
...
Word InsertBits(Word pos, Word count, Byte* buf)  //опустил проверку на выход за пределы
    Word byte_count = count / OCTET;
    auto
        shift_l = pos % OCTET,
        tail = count % OCTET,
        shift_r = shift_l + tail;
    auto local_array = bits_array+ (pos / OCTET);
    byte_count += shift_r / OCTET;
    if (shift_l) {
        *local_array =
            ((BYTE_MASK >> (OCTET - shift_l)) & *local_array)
            | ((*buf << shift_l) & (0xff << shift_l));
        local_array++;
        for (size_t i = 0; i < byte_count; ++i)
            local_array[i] = (Byte)(*(Word*)(buf + i) >> (OCTET - shift_l) & BYTE_MASK);
    }
    else
        ::memcpy(local_array, buf, byte_count);
    if (shift_r %= OCTET) {  //если остался хвост (с учётом смещения в начале)
        local_array[byte_count] =
            (((Byte)BYTE_MASK << shift_r) & local_array[byte_count])
            | ((buf[byte_count] >> (tail - shift_r)) & (BYTE_MASK >> (OCTET - shift_r)));
        byte_count++;
    }
    return byte_count;
}

Использовать сдвиги как замену умножения/деления - преждевременная оптимизация.
0
Модератор
Эксперт функциональных языков программированияЭксперт Python
31966 / 17647 / 3706
Регистрация: 12.02.2012
Сообщений: 29,697
Записей в блоге: 5
04.08.2016, 13:01 15
Сдвиги эффективны как замена умножения/деления на степень двойки (это быстрее умножения). Вот код, в котором перевод десятичного числа в int-форму выполнен без умножения на 10:

C++
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
#include <cstdlib>
#include <iostream>
 
using namespace std;
 
int d2b(char *s)
{ 
    int r,n,i;
    r=0;
    for (i=0; i<strlen(s); i++)
         r=(r<<1)+(r<<3)+(s[i]-'0');
    return r;     
}    
 
int main(int argc, char *argv[])
{
    char *S="3245";
    
    cout << d2b(S) << endl;
    
    system("PAUSE");
    return EXIT_SUCCESS;
}
0
0 / 0 / 0
Регистрация: 05.08.2016
Сообщений: 5
05.08.2016, 13:45 16
На собеседованиях очень любят спрашивать))
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
05.08.2016, 13:45
Помогаю со студенческими работами здесь

Циклический сдвиг целого числа на n разрядов влево и вправо
Такая ситуация. Написать функцию, циклически сдвигающую целое число на N разрядов вправо или влево,...

Циклический сдвиг битов в байте влево или вправо
Кто-нибудь пробовал реализовать такую задачу на С++. Если да, то какой алгоритм? Например, если...

Циклический сдвиг односвязного списка, организованного структурами, на N элементов вправо/влево
Подскажите, как лучше всего циклически сдвинуть односвязный список, организованный структурами, на...

Обеспечить сдвиг столбцов матрицы вправо или влево в зависимости от знака вводимого числа сдвигов
Дана целочисленная матрица размерности n x m. Обеспечить сдвиг столбцов матрицы вправо или влево в...


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

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

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin
Copyright ©2000 - 2022, CyberForum.ru