Форум программистов, компьютерный форум, киберфорум
С++ для начинающих
Войти
Регистрация
Восстановить пароль
 
 
Рейтинг 4.88/396: Рейтинг темы: голосов - 396, средняя оценка - 4.88
0 / 0 / 0
Регистрация: 13.12.2014
Сообщений: 4
1

Как работают побитовые сдвиги?

13.04.2007, 19:36. Показов 74633. Ответов 58
Метки нет (Все метки)

Люди объясните плиз как работают побитовые сдвиги
<< и >>, а то что то совсем запарился :confused:
0

Помощь в написании контрольных, курсовых и дипломных работ здесь.

Лучшие ответы (1)
Programming
Эксперт
94731 / 64177 / 26122
Регистрация: 12.04.2006
Сообщений: 116,782
13.04.2007, 19:36
Ответы с готовыми решениями:

Побитовые сдвиги
#include&lt;iostream&gt; int main() { int t=1; while(255&amp;t){ t=t&lt;&lt;t; std::cout&lt;&lt;t&lt;&lt;'\n';}...

Побитовые сдвиги
Был на собеседовании, была задачка, вроде такая: Есть функция, которая принимает char a (1 байт)...

Побитовые сдвиги
нужна помощь с заданием на С++: При написании функций можно использовать только следующее: -...

Программа на побитовые сдвиги
Привет! Выполнить путём сдвига вправо все биты, значение которых равно нулю и влево все биты,...

58
25 / 24 / 1
Регистрация: 03.03.2007
Сообщений: 4
14.04.2007, 16:00 2
Лучший ответ Сообщение было отмечено как решение

Решение

Все банально просто...
val << n - это сдвиг влево переменной val на n разрядов. то же самое что умножение на 2 в определенной степени.
пример:
int val = 4;
int temp = val << 3;
в результате temp=32. по другому это val*(2^3);

val >> n - это сдвиг вправо переменной val на n разрядов. то же самое что деление на 2 в определенной степени.
пример:
int val = 4;
int temp = val >> 2;
в результате temp=1. по другому это val/(2^2);

Вот в принципе и все...
Желаю удачи
24
12 / 12 / 4
Регистрация: 16.03.2007
Сообщений: 109
15.04.2007, 13:17 3
Скачай книгу про C++. Вот цитата из рукодовства:
Операции сдвига << и >> группируют слева направо. Обе выполняют
одно обычное арифметическое преобразование над своими операндами,
каждый из которых должен быть целым. В этом случае правый операнд
преобразуется к типу int; тип результата совпадает с типом левого
операнда. Результат неопределен, если правый операнд отрицателен
или больше или равен длине объекта в битах.

- стр 270 -

сдвиговое_выражение:
выражение << выражение
выражение >> выражение
Значением Е1 << Е2 является Е1 (рассматриваемое как битовое
представление), сдвинутое влево на Е2 битов; освободившиеся биты
заполняются нулями. Значением Е1 >> Е2 является Е1 , сдвинутое
вправо на Е2 битовых позиций. Гарантируется, что сдвиг вправо
является логическим (заполнение нулями), если Е1 является unsigned;
в противном случае он может быть арифметичевким (заполнение копией
знакового бита).
0
24 / 14 / 2
Регистрация: 20.02.2010
Сообщений: 181
03.09.2013, 19:59 4
А можно ли как-то получить старший сдвинутый бит при побитовом сдвиге влево?
Т.е. есть число 1001001
применяем операцию сдвига влево на 1 бит какой-то функцией my_func_shift(int a)
получаем 0010010, но функция возвращает сдвинутый старший бит единицу.
Есть такая функция в плюсах?
0
3418 / 2777 / 752
Регистрация: 25.03.2012
Сообщений: 10,101
Записей в блоге: 1
03.09.2013, 20:05 5
тема старая.
нафига тебе получать этот бит?
А если сдвиг не на 1 влево, а на 2,3...n?
Не легче отдельной операцией получить старшие биты, сдвинув исходное число на n-1 вправо?
0
24 / 14 / 2
Регистрация: 20.02.2010
Сообщений: 181
03.09.2013, 20:10 6
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
нафига тебе получать этот бит?
Какая разница? Необходимо.
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
А если сдвиг не на 1 влево, а на 2,3...n?
Требуется только на 1 бит.
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Не легче отдельной операцией получить старшие биты, сдвинув исходное число на n-1 вправо?
Нецелесообразно с точки зрения производительности.
0
3418 / 2777 / 752
Регистрация: 25.03.2012
Сообщений: 10,101
Записей в блоге: 1
03.09.2013, 20:28 7
Цитата Сообщение от broDiaga_cpp Посмотреть сообщение
Нецелесообразно с точки зрения производительности.
Какой ещё производительности? Ты не о производительности думай!
Короче, ответ: нет.
0
Модератор
Эксперт по электронике
8495 / 6321 / 855
Регистрация: 14.02.2011
Сообщений: 21,915
03.09.2013, 20:36 8
Цитата Сообщение от broDiaga_cpp Посмотреть сообщение
Есть такая функция в плюсах?
нет
но можно сделать
C++
1
2
3
4
5
6
7
int Myfunc(int & aa)
{
 unsigned int tmp=0x80000000&aa;// выделяем старший бит
 aa=aa<<1;// сдвиг
 tmp>>=31;//старший бит загоняем в младший
return tmp; 
}
1
24 / 14 / 2
Регистрация: 20.02.2010
Сообщений: 181
03.09.2013, 20:43 9
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
Какой ещё производительности? Ты не о производительности думай!
Если бы речь шла о лабе в институте - я бы согласился, что плевать на производительность. Но речь идёт не о лабе и на счету каждая миллисекунда.
0
Модератор
Эксперт по электронике
8495 / 6321 / 855
Регистрация: 14.02.2011
Сообщений: 21,915
03.09.2013, 20:56 10
Цитата Сообщение от broDiaga_cpp Посмотреть сообщение
Но речь идёт не о лабе и на счету каждая миллисекунда.
за одну миллисекунду пройдут тысячи операций
и кто тебе сказал что винда "система реального времени"
1
2622 / 2210 / 237
Регистрация: 03.07.2012
Сообщений: 7,982
Записей в блоге: 1
03.09.2013, 22:13 11
Цитата Сообщение от broDiaga_cpp Посмотреть сообщение
Если бы речь шла о лабе в институте - я бы согласился, что плевать на производительность. Но речь идёт не о лабе и на счету каждая миллисекунда.
А если "дорога каждая миллисекунда" - делай ассемблерную вставку/процедуру с циклическим сдвигом или с использованием флажка процессора.
0
0 / 0 / 0
Регистрация: 30.06.2015
Сообщений: 189
26.12.2017, 20:35 12
Если надо установить биты 7-0 RXCIE TXCIE UDRIE RXEN TXEN UCSZ2 RXB8 TXB8 регистра UCSRB

C
1
UCSRB=(1<<RXEN)|( 1<<TXEN); //Включаем прием и передачу по USART
Только непонятно, если надо биты RXEN и TXEN установить в единицу, то исходя из определения операции побитового сдвига, 1 сдвигается влево на содержимое данных битов.
И каким образом тогда значение регистра становится равным сумме этих сдвигов, тоже не совсем понятно, обьясните, пожалуйста, в чем тут дело?

(то есть то, что эта операция их устанавливает в 1, это точно известно,т.к. везде так написано. И программа с таким текстом работает. Но нигде не могу найти обьяснения, как это выводится из правил операции побитового сдвига)

Добавлено через 14 минут
то есть понятно, что если эти биты равны 0, то 1 как раз в них и установится, а если нет? Она ведь сьедет в другой бит тогда, а может быть его значение не нужно менять?
А ведь операция предварительного обнуления этих битов не была записана, т.е. мы надеемся, что после RESET они нулевые?
А ведь есть некоторые биты, значения которых по дефолту как раз "1".

Обьясните мне пожалуйста эту хитрость.

Добавлено через 1 минуту
я имел в виду биты
C
1
RXCIE TXCIE UDRIE RXEN TXEN UCSZ2 RXB8 TXB8
регистра UCSRB

Добавлено через 5 минут
то есть почему просто не пишут в таком случае:
C++ (Qt)
1
UCSRB |= 0x00011000
ведь в таком случае только эти биты изменят свое значение на 1, а осталные не поменяют свое значение?
0
991 / 848 / 202
Регистрация: 29.09.2015
Сообщений: 980
26.12.2017, 20:47 13
Чесн, не знаком с таким интерфейсом.
RXEN и TXEN имеют постоянные значения?
В рамках какого числа живет UCSRB (...,8,16,32,... бит) ?

Цитата Сообщение от design_m Посмотреть сообщение
UCSRB |= 0x00011000
В первом примере у вас UCSRB принимающее, а тут... создается впечатление, что оно имеет какое то уже значение и вы пытаетесь выполнить побитовое сложение с ним
0
3418 / 2777 / 752
Регистрация: 25.03.2012
Сообщений: 10,101
Записей в блоге: 1
26.12.2017, 20:56 14
Цитата Сообщение от design_m Посмотреть сообщение
то есть почему просто не пишут в таком случае:
UCSRB |= 0x00011000
потому что 0x00011000 число шестнадцатиричное, а не двоичное, как бы тебе хотелось.
ты имел в виду UCSRB |= 0x18
design_m, а какая разница так или так?
C++
1
2
UCSRB |= 0x18;
UCSRB=(1<<RXEN)|( 1<<TXEN);
в чём вопрос-то? посчитай на бумажке значение (1<<RXEN)|( 1<<TXEN) и как раз получишь 0x18
0
зомбяк
1533 / 1178 / 332
Регистрация: 14.05.2017
Сообщений: 3,824
26.12.2017, 21:08 15
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
0x00011000
Двоичные числа во многих компиляторах записываются как
C++
1
0b00011000
но стандартом это не поддерживается и считается дурным тоном. Хорошим считается 16-ричное представление.
0
Модератор
Эксперт по электронике
8495 / 6321 / 855
Регистрация: 14.02.2011
Сообщений: 21,915
26.12.2017, 21:21 16
design_m, ну и что не понятно?
например TXEN=5 а RXEN=1( подробней смотри даташит на свой микроконтроллер)
итого
UCSRB=(1<<1)|( 1<<5);
UCSRB=(0x02)|( 0x20);
UCSRB=0x22;
и такие вопросы лучше задавать в https://www.cyberforum.ru/microcontrollers/
быстрей ответят
0
1025 / 707 / 316
Регистрация: 26.02.2015
Сообщений: 3,205
26.12.2017, 21:26 17
Цитата Сообщение от TRam_ Посмотреть сообщение
дурным тоном
Настолько дурным, что о них Страуструп рассказывает?
0
Модератор
Эксперт по электронике
8495 / 6321 / 855
Регистрация: 14.02.2011
Сообщений: 21,915
26.12.2017, 21:29 18
Цитата Сообщение от Nishen Посмотреть сообщение
что о них Страуструп рассказывает?
и где это используется, кроме AVRовских компиляторов ( туда же и Ардуино отнесем)
0
1025 / 707 / 316
Регистрация: 26.02.2015
Сообщений: 3,205
26.12.2017, 21:39 19
Цитата Сообщение от ValeryS Посмотреть сообщение
и где это используется, кроме AVRовских компиляторов ( туда же и Ардуино отнесем)
Думаю это используется в AVRовских компиляторах (туда можете отнести Ардуино). Я не о способах применения сего, а о том, что это стандартизированно, начиная с C++14.
0
0 / 0 / 0
Регистрация: 30.06.2015
Сообщений: 189
26.12.2017, 22:55 20
так это я просто ошибся, по инерции
конечно, там надо было b а не x писать.

Но суть вопроса же не меняется - в общем случае ведь неизвестно, какие значения у битов по дефолту?

Добавлено через 15 минут
Цитата Сообщение от ValeryS Посмотреть сообщение
например TXEN=5 а RXEN=1( подробней смотри даташит на свой микроконтроллер)
они не могут быть 5 и 1, это не регистры, а биты. я там выше привел расположение этих битов в регистре UCSRB,
C
1
0b00011000
они принимают значения либо 0 либо 1.

Я имею в виду, в общем случае, если вдруг бит не 0, то ведь тогда такая запись не установит его в 1 (судя по правилам битовых сдвигов) и хочу понять, в чем тут дело, раз все таким способом пользуются.

(на самом деле я просто глупо переписываю этот код в свои программы, и всё работает, но хочется понять смысл этой записи)

Добавлено через 4 минуты
Цитата Сообщение от ValeryS Посмотреть сообщение
UCSRB=0x22;
так если такой результат получится, то будут установлены в 1 совсем другие биты, чем нужно -
C
1
0b00100010
а должны быть установлены биты
C
1
0b00011000
Добавлено через 8 минут
Цитата Сообщение от Kuzia domovenok Посмотреть сообщение
посчитай на бумажке значение (1<<RXEN)|( 1<<TXEN) и как раз получишь 0x18
так эти выражения имеют одинаковое значение, я об этом и писал в своем вопросе.

Но везде пишут не
C
1
0b00011000
а именно
C
1
 (1<<RXEN)|( 1<<TXEN)
так я хочу понять, в чем тут дело, ведь если эти биты не равны 0, то эта запись не установит их в 1?
0
IT_Exp
Эксперт
87844 / 49110 / 22898
Регистрация: 17.06.2006
Сообщений: 92,604
26.12.2017, 22:55

Не работают побитовые операции с++
Использую Microsoft Visual Studio 2012 Express Этот код компилируется, но в переменную с...

Побитовые сдвиги
Объясните, почему сдвиг битов влево значит умножению на степень двойки. Пример: 6 &lt;&lt; 1 = 6 * 2;...

Побитовые сдвиги
Где применяются побитовые сдвиги и зачем? Вроде не ассемблер учу а тут такое :О

Побитовые сдвиги
Помогите с задачкой :( сопоставить результаты побитового сдвига на*n*бит влево*m&lt;&lt;n* и...


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

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

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