Форум программистов, компьютерный форум CyberForum.ru

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

Войти
Регистрация
Восстановить пароль
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 5.00
Thinker
Эксперт C++
4225 / 2199 / 150
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5
#1

Поразрядные операторы сдвига - C++

27.08.2011, 11:03. Просмотров 2338. Ответов 5
Метки нет (Все метки)

Всем хорошо известно, что поразрядные операторы сдвига >> и << сдвигают все биты переменной вправо или влево. Во время сдвига битов в один конец числа, другой конец заполняется нулями (ограничимся рассмотрением переменных без знака). Данные сдвиги не являются циклическими.

Так вот столкнулся с ситуацией, что если n - количество разрядов переменной, например x, то
x << (n - 1 + i) == x << i,
где 0 < i < n. Например,

unsigned long x;
x = 1 << 32; ( == 1 << 1)
x = 1 << 33; ( == 1 << 2)

Казалось бы, что переменная x во всех случаях должна быть равна 0, но нет, совсем нет.
Кто-нибудь знает почему это так и где это прописано? Можно написать формулу:
unsigned long x = 1 << n; (== 1 << (n % (sizeof(x)*8)));

Со сдвигом вправо таких странностей нет.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
27.08.2011, 11:03
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Поразрядные операторы сдвига (C++):

Поразрядные операторы,операторы сдвига - C++
#include&lt;iostream&gt; using namespace std; int bitcount(unsigned x) { int b; for(b=0;x!=0;x&gt;&gt;=1) if(x&amp;01) b++; return...

Поразрядные операторы - C++
Здравствуйте, объясните мне практическую ценность поразрядных операторов, не могу понять, зачем они нужны.. заранее спасибо.

Поразрядные операторы + небольшая шифропрограммка - C++
Начинаю изучать поразрядные операторы (и, или, исключающее или, не). В принципе все понятно, но при написании небольшой (детской)...

С++.Операторы в С++: условные операторы, операторы break и continue - C++
Выяснить, пересекаются ли параболы у=аx2+bx+с и у=dx2+ex + f. При положительном ответе найти точки пересечения.

Определить и вывести количество дней между двумя датами (логические операторы и операторы ветвлений) - C++
Задачка Пользователь вводит две даты (день, месяц, год в виде целых чисел). Необходимо определить и вывести количество дней между этими...

Операторы присваивания, ввода- вывода. Операторы ветвления, выбора - C++
Даны два ненулевых числа. Найти их сумму, разность, произведение, частное, остаток и целую часть от деления. Добавлено через 8 часов...

Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
grizlik78
Эксперт С++
1908 / 1440 / 111
Регистрация: 29.05.2011
Сообщений: 2,996
27.08.2011, 11:26 #2
Цитата Сообщение от Thinker Посмотреть сообщение
unsigned long x;
x = 1 << 32; ( == 1 << 1)
x = 1 << 33; ( == 1 << 2)
Первый раз слышу. Что за компилятор? Можно маленький, но законченный пример кода?
Somebody
2788 / 1602 / 145
Регистрация: 03.12.2007
Сообщений: 4,193
Завершенные тесты: 1
27.08.2011, 11:27 #3
Стандарт C++:
http://www.open-std.org/jtc1/sc22/op...tml#expr.shift
The operands shall be of integral or enumeration type and integral
promotions are performed. The type of the result is that of the pro-
moted left operand. The behavior is undefined if the right operand is
negative, or greater than or equal to the length in bits of the pro-
moted left operand.
Так что может быть что угодно. Размер непосредственного операнда у инструкций сдвига - 8 бит, так что, видимо, компилятор так и компилит сдвиг на 33 (или при вычислении константы сдвигает). Далее описание инструкций:
http://www.intel.com/content/dam/doc...a-z-manual.pdf
The destination operand can be a register or a memory location. The count operand
can be an immediate value or the CL register. The count is masked to 5 bits (or 6 bits
if in 64-bit mode and REX.W is used). The count range is limited to 0 to 31 (or 63 if
64-bit mode and REX.W is used). A special opcode encoding is provided for a count
of 1.
А вообще компилятор должен бы warning давать при таком.
Thinker
Эксперт C++
4225 / 2199 / 150
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5
27.08.2011, 11:39  [ТС] #4
Цитата Сообщение от grizlik78 Посмотреть сообщение
Первый раз слышу. Что за компилятор? Можно маленький, но законченный пример кода?
Такой глюк на acmp есть, голову ломал почему некоторые тесты не проходят, а дело в этом оказалось. Компилятор тут не причем, раз на одном глючит, то и на другом тоже так может быть. Но вот такая интересная особенность, никогда не думал, что такие ловушки могут быть.

Можно и код:
C++
1
2
unsigned long x = 1 << 100;
std::cout << x;
На экране: 16
grizlik78
Эксперт С++
1908 / 1440 / 111
Регистрация: 29.05.2011
Сообщений: 2,996
27.08.2011, 11:43 #5
Ну что ж, остаётся только согласиться, что это UB и не использовать такой код.
Thinker
Эксперт C++
4225 / 2199 / 150
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5
27.08.2011, 11:50  [ТС] #6
Цитата Сообщение от Somebody Посмотреть сообщение
А вообще компилятор должен бы warning давать при таком.
Сдвиг зависел от значения переменной.
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
27.08.2011, 11:50
Привет! Вот еще темы с ответами:

«Языки и технологии программирования» «Операторы цикла. Условные операторы» - C++
Не получается сделать что бы программа выводила все значения в промежутке, она выводит только одно. условия | ((z^3)+sin...

Операторы языка С++: операторы цикла (исправьте программу) - C++
#include &lt;iostream&gt; #include &lt;cstdlib&gt; #include &lt;cmath&gt; using namespace std; int main() { int a,n; float y,x; cout&lt;&lt;...

Операторы цикла и операторы передачи управления - C++
Вычислить сумму ряда S с погрешностью эпсилон, задаваемой с клавиатуры. Вывести количество итераций, сделанных при вычислении. Если...

Операторы принятия решения и операторы цикла. - C++
Пожалуйста, помогите. Нужно срочно сделать задания: 1)Ввести с клавиатуры три символа sym1, sym2, sym3. Поменять их значения таким...


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

Или воспользуйтесь поиском по форуму:
Yandex
Объявления
27.08.2011, 11:50
Ответ Создать тему
Опции темы

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