如何将长位移位超过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 << 371L << 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