C++ 如何将 long 移位超过 32 位?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/2404439/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I bit shift a long by more than 32 bits?
提问by Cthutu
It seems like I should be able to perform bit shift in C/C++ by more than 32 bits provided the left operand of the shift is a long. But this doesn't seem to work, at least with the g++ compiler.
如果移位的左操作数很长,我似乎应该能够在 C/C++ 中执行超过 32 位的移位。但这似乎不起作用,至少在 g++ 编译器中是这样。
Example:
例子:
unsigned long A = (1L << 37)
gives
给
A = 0
which isn't what I want. Am I missing something or is this just not possible?
这不是我想要的。我错过了什么还是这不可能?
-J
-J
采纳答案by bta
Re-try this using a variable of type uint64_t
(from stdint.h
) instead of long
. uint64_t
is guaranteed to be 64 bits long and should behave as you expect.
使用类型为uint64_t
(from stdint.h
) 而不是long
. uint64_t
保证为 64 位长,并且应该按照您的预期运行。
回答by Cthutu
A is equal to 0 because A only has 32-bits, so of course you are shifting all the bits off to the left leaving only 0 bits left. You need to make A 64-bit:
A 等于 0,因为 A 只有 32 位,所以当然您将所有位向左移,只剩下 0 位。你需要做一个 64 位的:
unsigned long long A = (1ULL << 37);
Or if you intend to use Visual C++:
或者,如果您打算使用 Visual C++:
unsigned __int64 A = (1ULL << 37);
回答by AnT
Well, it depends on the actual size of the type long
(more precisely, its widthin bits). Most likely on your platform long
has width of 32 bits, so you get 0
as the result (also, see P.S. below). Use a bigger type. long long
maybe?
嗯,这取决于类型的实际大小long
(更准确地说,它的宽度以位为单位)。最有可能在您的平台上long
具有 32 位的宽度,因此您会得到0
结果(另请参阅下面的 PS)。使用更大的类型。long long
也许?
P.S. As an additional note, shifting a type by more bits than its width (or equal number of bits) produces undefined behaviorin C and C++ (C++ uses the term lengthinstead of width). So, you are not guaranteed to get 0
from neither 1L << 37
nor 1L << 32
on a platform where long
has width 32.
PS 作为附加说明,将类型移位比其宽度(或相等数量的位数)多的位会在 C 和 C++ 中产生未定义的行为(C++ 使用术语length而不是width)。因此,不能保证您0
既不在1L << 37
也不1L << 32
在long
宽度为 32的平台上。
回答by Paul R
Are you sure that a long is 64 bits with your particular OS and compiler ? Use stdint.h and try it like this:
您确定您的特定操作系统和编译器的 long 是 64 位吗?使用 stdint.h 并像这样尝试:
#include <stdint.h>
uint64_t x = (1ULL << 37);
回答by Kirill V. Lyadvinsky
New C++ Standard introduces LL and ULL suffixes for integer literals. You could try to use them since all latest compilers supports them. But you should know that it is not part of current C++ Standard.
新的 C++ 标准为整数文字引入了 LL 和 ULL 后缀。您可以尝试使用它们,因为所有最新的编译器都支持它们。但是您应该知道它不是当前 C++ 标准的一部分。
long long A = (1LL << 37)
回答by sw.
回答by norman graham
You have the arguments reversed.
你的论点颠倒了。
unsigned long A1 = (1L << 37); // is 2 to the 37th
unsigned long A = (37UL<<1UL); // has just multiplied 37 by 2