如何将长位移位超过32位?
看起来如果移位的左操作数很长,我应该能够在C / C ++中执行超过32位的位移。 但这似乎不起作用,至少使用g ++编译器。
例:
unsigned long A = (1L << 37)
给
A = 0
这不是我想要的。 我错过了什么或者这是不可能的吗?
-J
使用类型为uint64_t
的变量(来自stdint.h
)而不是long
来重试此方法。 uint64_t
保证长度为64位,并且应该按预期运行。
A等于0,因为A只有32位,所以当然你将所有位都移到左边,只留下0位。 你需要制作一个64位的:
unsigned long long A = (1ULL << 37);
或者如果您打算使用Visual C ++:
unsigned __int64 A = (1ULL << 37);
嗯,这取决于类型的实际大小(更确切地说,它的宽度以位为单位)。 最有可能在您的平台上长度为32位,因此结果为0
(另请参阅下面的PS)。 使用更大的类型。 long long
?
PS作为补充说明,将类型移位的位数多于其宽度(或相等的位数)会在C和C ++中产生未定义的行为 (C ++使用术语长度而不是宽度 )。 因此,在长度为1L << 32
的平台上,不保证从1L << 37
和1L << 32
得到0
。
您确定您的特定操作系统和编译器的长度是64位吗? 使用stdint.h并尝试这样:
#include uint64_t x = (1ULL << 37);
新C ++标准为整数文字引入了LL和ULL后缀。 您可以尝试使用它们,因为所有最新的编译器都支持它们。 但是你应该知道它不是当前C ++标准的一部分。
long long A = (1LL << 37)
在您的情况下,您仅限于语言基础类型。 [准]任意大小整数的通用解决方案是在Crypto ++下使用Integer类。
你有相反的论点。
unsigned long A1 = (1L << 37); // is 2 to the 37th unsigned long A = (37UL<<1UL); // has just multiplied 37 by 2