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

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

Восстановить пароль Регистрация
 
Рейтинг: Рейтинг темы: голосов - 18, средняя оценка - 5.00
Thinker
Эксперт C++
 Аватар для Thinker
4215 / 2189 / 150
Регистрация: 26.08.2011
Сообщений: 3,802
Записей в блоге: 5
27.08.2011, 11:03     Поразрядные операторы сдвига #1
Всем хорошо известно, что поразрядные операторы сдвига >> и << сдвигают все биты переменной вправо или влево. Во время сдвига битов в один конец числа, другой конец заполняется нулями (ограничимся рассмотрением переменных без знака). Данные сдвиги не являются циклическими.

Так вот столкнулся с ситуацией, что если 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)));

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

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