Как операторы сдвига влияют на числа без знака - PullRequest
0 голосов
/ 01 мая 2018

Предположим, x является беззнаковым int

Тогда x << n равно x * 2 n

Я знаю, что это верно для целых чисел со знаком.

x * 15 1014 * равно x << 4 - x?

1 Ответ

0 голосов
/ 01 мая 2018

Этот ответ для языка Си. В этом конкретном вопросе, похоже, есть тонкие различия в спецификации C ++.

Если x является беззнаковым и , если n >= 0 и меньше, чем число битов значения в типе x, x << n действительно совпадает с умножением x на n-я степень 2.

Если это вычисление переполнится, результат будет уменьшен по модулю наибольшего значения для типа x плюс 1.

Если x подписано, оно должно быть неотрицательным, результат не должен быть переполнен, иначе вы получите неопределенное поведение. Типичный случай неопределенного поведения на 32-битных архитектурах таков:

unsigned x = 1 << 31;   /* undefined behavior: 1 is signed, 31 is too large */

Правильная версия:

unsigned x = 1U << 31;   /* correct on 32 bit architectures */

Кстати, начиная с C ++ 14, в стандарте C ++ есть конкретное положение для этого самого случая:

значение a << b умножается на 2 b , если оно представимо в беззнаковой версии возвращаемого типа (который затем преобразуется в подписанный: это делает законным создание INT_MIN как 1 << 31), иначе поведение не определено.

По второму вопросу x * 15 равно x << 4 - x?

Ответ - нет, потому что x << 4 - x анализируется как x << (4 - x).

Если вы заключите в скобки свое выражение, тогда действительно x * 15 == (x << 4) - x.

Обратите внимание, что это не правильно для значений со знаком, потому что промежуточный результат x << 4 может переполниться для больших значений x, для которых результат x * 15 не будет.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...