Как делают меня сдвиг разряда длинное больше чем на 32 бита? [дубликат]

Этот вопрос уже имеет ответ здесь:

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

Пример:

unsigned long A = (1L << 37)

дает

A = 0

который не является тем, что я хочу. Я пропускаю что-то, или разве это просто не возможно?

- J

24
задан 8 March 2010 в 20:20
поделиться

6 ответов

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

14
ответ дан 28 November 2019 в 23:08
поделиться

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

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

Или, если вы собираетесь использовать Visual C++:

unsigned __int64 A = (1ULL << 37);
26
ответ дан 28 November 2019 в 23:08
поделиться

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

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

10
ответ дан 28 November 2019 в 23:08
поделиться

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

long long A = (1LL << 37)
0
ответ дан 28 November 2019 в 23:08
поделиться

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

0
ответ дан 28 November 2019 в 23:08
поделиться

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

#include <stdint.h>

uint64_t x = (1ULL << 37);
3
ответ дан 28 November 2019 в 23:08
поделиться