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

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

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

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

27.08.2011, 11:03. Просмотров 2244. Ответов 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++
Поразрядные операции C++
поразрядные операции C++
поразрядные операции C++
C++ Поразрядные поразрядное И (&)
C++ Поразрядные операции
C++ Поразрядные операции
C++ Поразрядные операции (&,|,^)
C++ Поразрядные операции
Поразрядные операции C++
Поразрядные операции C++

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

Или воспользуйтесь поиском по форуму:
После регистрации реклама в сообщениях будет скрыта и будут доступны все возможности форума.
grizlik78
Эксперт С++
 Аватар для grizlik78
1892 / 1424 / 105
Регистрация: 29.05.2011
Сообщений: 2,980
27.08.2011, 11:26     Поразрядные операторы сдвига #2
Цитата Сообщение от Thinker Посмотреть сообщение
unsigned long x;
x = 1 << 32; ( == 1 << 1)
x = 1 << 33; ( == 1 << 2)
Первый раз слышу. Что за компилятор? Можно маленький, но законченный пример кода?
Somebody
2775 / 1589 / 142
Регистрация: 03.12.2007
Сообщений: 4,162
Завершенные тесты: 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++
 Аватар для Thinker
4218 / 2192 / 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
Эксперт С++
 Аватар для grizlik78
1892 / 1424 / 105
Регистрация: 29.05.2011
Сообщений: 2,980
27.08.2011, 11:43     Поразрядные операторы сдвига #5
Ну что ж, остаётся только согласиться, что это UB и не использовать такой код.
Thinker
Эксперт C++
 Аватар для Thinker
4218 / 2192 / 150
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5
27.08.2011, 11:50  [ТС]     Поразрядные операторы сдвига #6
Цитата Сообщение от Somebody Посмотреть сообщение
А вообще компилятор должен бы warning давать при таком.
Сдвиг зависел от значения переменной.
Yandex
Объявления
27.08.2011, 11:50     Поразрядные операторы сдвига
Ответ Создать тему
Опции темы

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