Подтвердить что ты не робот

Как я могу бить сдвиг длиннее более чем на 32 бита?

Похоже, я должен иметь возможность выполнять сдвиг бит в C/С++ более чем на 32 бита, если левый операнд сдвига длинный. Но это, похоже, не работает, по крайней мере, с компилятором g++.

Пример:

unsigned long A = (1L << 37)

дает

A = 0

что я не хочу. Я что-то упустил или это просто невозможно?

-J

4b9b3361

Ответ 1

Повторите попытку, используя переменную типа uint64_t (от stdint.h) вместо long. uint64_t гарантированно имеет длину 64 бит и должен вести себя так, как вы ожидаете.

Ответ 2

A равно 0, поскольку A имеет только 32 бита, поэтому, конечно, вы смещаете все биты слева, оставляя только 0 бит влево. Вам нужно сделать 64-разрядную версию:

unsigned long long A = (1ULL << 37);

Или если вы намереваетесь использовать Visual С++:

unsigned __int64 A = (1ULL << 37);

Ответ 3

Ну, это зависит от фактического размера типа long (точнее, его ширины в битах). Скорее всего, на вашей платформе long будет ширина 32 бит, поэтому вы получите 0 в качестве результата (также см. Ниже P.S.). Используйте больший тип. long long может быть?

P.S. В качестве дополнительного примечания, сдвиг типа на большее число бит, чем его ширина (или равное количество бит), создает поведение undefined в C и С++ (С++ использует длину слова вместо ширины). Таким образом, вы не можете получить 0 от 1L << 37 и 1L << 32 на платформе, где long имеет ширину 32.

Ответ 4

Вы уверены, что длинный 64 бит с вашей конкретной ОС и компилятором? Используйте stdint.h и попробуйте сделать это следующим образом:

#include <stdint.h>

uint64_t x = (1ULL << 37);

Ответ 5

Новый стандарт С++ вводит суффиксы LL и ULL для целых литералов. Вы можете попытаться использовать их, поскольку все последние компиляторы поддерживают их. Но вы должны знать, что он не является частью текущего стандарта С++.

long long A = (1LL << 37)

Ответ 6

В вашем случае вы ограничены языковыми типами. Общее решение для [квази] произвольных размерных чисел использует Integer класс под Crypto ++.

Ответ 7

У вас есть аргументы в обратном порядке.

unsigned long A1 = (1L << 37); // is 2 to the 37th 
unsigned long A = (37UL<<1UL); // has just multiplied 37 by 2