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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-27 23:23:31  来源:igfitidea点击:

How do I bit shift a long by more than 32 bits?

c++c

提问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_tis 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 longhas width of 32 bits, so you get 0as the result (also, see P.S. below). Use a bigger type. long longmaybe?

嗯,这取决于类型的实际大小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 0from neither 1L << 37nor 1L << 32on a platform where longhas width 32.

PS 作为附加说明,将类型移位比其宽度(或相等数量的位数)多的位会在 C 和 C++ 中产生未定义的行为(C++ 使用术语length而不是width)。因此,不能保证您0既不在1L << 37也不1L << 32long宽度为 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.

In your case you're restricted to the language base types. A generic solution for [quasi] arbitrary size integers is using Integerclass under Crypto++.

在您的情况下,您仅限于语言基础类型。[准] 任意大小整数的通用解决方案是使用Crypto++下的Integer类。

回答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