长型64位linux
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/10040123/
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
Long type 64bit linux
提问by de1337ed
Very simple questions guys, but maybe I'm just forgetting something. In 64bit linux, a long is 8bytes correct? If that's the case, and I want to set the 64th bit, I can do the following:
很简单的问题伙计们,但也许我只是忘记了一些东西。在 64 位 linux 中,long 是 8bytes 正确吗?如果是这种情况,并且我想设置第 64 位,我可以执行以下操作:
unsigned long num = 1<<63;
Whenever I compile this, however, it gives me an error saying that I'm left shifting by more than the width. Also, if I wanted to take the first 32bits of a long type (without sign extension), can I do:
然而,每当我编译它时,它都会给我一个错误,说我左移的幅度超过了宽度。另外,如果我想获取 long 类型的前 32 位(没有符号扩展),我可以这样做:
num = num&0xFFFFFFFF;
or what about:
或者呢:
num = (int)(num);
Thank you.
谢谢你。
采纳答案by Pavan Manjunath
In 64bit linux, a long is 8bytes correct?
在 64 位 linux 中,long 是 8bytes 正确吗?
Need not be. Depends on the compiler than on the underlying OS. Check this for a nice discussion. What decides the sizeof an integer?
不必如此。取决于编译器而不是底层操作系统。检查这个 一个很好的讨论。 什么决定整数的大小?
Whenever I compile this, however, it gives me an error saying that I'm left shifting by more than the width
然而,每当我编译这个时,它都会给我一个错误,说我左移的幅度超过了宽度
Everyone have already answered this. Use 1UL
这个大家都已经回答过了。用1UL
Also, if I wanted to take the first 32bits of a longtype (without sign extension), can I do:
另外,如果我想获取long类型的前 32 位(没有符号扩展),我可以这样做:
num = num&0xFFFFFFFF;
or what about:
num = (int)(num);
num = num&0xFFFFFFFF
. This will give you the lower 32-bits. But note that if long
is just 4 bytes on your system then you are getting the entire number. Coming to the sign extension part, if you've used a long
and not unsigned long
then you cannot do away with the sign extended bits. For example, -1
is represented as all ones, right from the 0th bit. How will you avoid these ones by masking?
num = num&0xFFFFFFFF
. 这将为您提供较低的 32 位。但请注意,如果long
您的系统上只有 4 个字节,那么您将获得整个数字。来到符号扩展部分,如果你使用了 along
而 notunsigned long
那么你就不能去掉符号扩展位。例如,-1
从第 0 位开始表示为全 1。你将如何通过屏蔽来避免这些?
num = (int)(num)
will give you the lower 32-bits but compiler might through a Overflow Exception warning if num
does not fit into an int
num = (int)(num)
将为您提供较低的 32 位,但如果num
不适合,编译器可能会通过溢出异常警告int
回答by Michael
I believe the problem with the first question is that the compiler is treating '1' as an integer, not as a long integer. It doesn't figure it out until after the assignment.
我相信第一个问题的问题在于编译器将 '1' 视为整数,而不是长整数。直到分配后才弄清楚。
You can fix it by doing:
您可以通过执行以下操作来修复它:
unsigned long num = (unsigned long)1<<63;
回答by Basile Starynkevitch
Actually, if you want some precise length (in bits) for your integers, assuming a C99conforming compiler, #include <stdint.h>
and use types like int64_t
, int32_t
etc. A handy type is intptr_t
, an integer type with the same number of bits as void*
pointer (so you can call it a machine "word")
实际上,如果你想要一些精确的整数长度(以位为单位),假设一个符合C99 的编译器,#include <stdint.h>
并使用类似的类型int64_t
,int32_t
等等。一个方便的类型是intptr_t
,一个与void*
指针具有相同位数的整数类型(所以你可以调用它是一个机器“词”)
回答by Morpfh
For portability you could use:
为了便于携带,您可以使用:
limits.h
限制.h
#define LNG_BIT (sizeof(long) * CHAR_BIT)
unsigned long num = 1UL << (LNG_BIT - 1);
To get "low int", something like?:
要获得“低整数”,例如?:
#define INT_BIT (sizeof(int) * CHAR_BIT)
if (LNG_BIT > INT_BIT)
return num & (~0UL >> INT_BIT);
else
return num;
or
或者
num &= ~(~0U << INT_BIT);
Or, use mask, etc. Depends in large on why, for what, etc. you want the int bits.
或者,使用掩码等。很大程度上取决于您想要 int 位的原因、用途等。
Also notice the options given by compilers; I.e. if you are using gcc:
还要注意编译器给出的选项;即,如果您使用 gcc:
-m32
-m64
-mx32
Generate code for a 32-bit or 64-bit environment.
* The -m32 option sets int, long, and pointer types to 32 bits, and generates code that runs on any i386 system.
* The -m64 option sets int to 32 bits and long and pointer types to 64 bits, and generates code for the x86-64 architecture. For Darwin only the -m64 option also turns off the -fno-pic and -mdynamic-no-pic options.
* The -mx32 option sets int, long, and pointer types to 32 bits, and generates code for the x86-64 architecture.
-m32
-m64
-mx32
为 32 位或 64 位环境生成代码。
* -m32 选项将 int、long 和指针类型设置为 32 位,并生成可在任何 i386 系统上运行的代码。
* -m64 选项将 int 设置为 32 位,将 long 和指针类型设置为 64 位,并为 x86-64 架构生成代码。对于达尔文,只有 -m64 选项也会关闭 -fno-pic 和 -mdynamic-no-pic 选项。
* -mx32 选项将 int、long 和指针类型设置为 32 位,并为 x86-64 架构生成代码。
There is also -maddress-mode=long
etc.
还有-maddress-mode=long
等等。
-maddress-mode=long
Generate code for long address mode. This is only supported for 64-bit and x32 environments. It is the default address mode for 64-bit environments.
-maddress-mode=long 生
成长地址模式的代码。这仅支持 64 位和 x32 环境。它是 64 位环境的默认地址模式。
回答by Gunther Piez
AFAIR code like this was the source of a major bug in reiserfs a few years ago:
几年前,像这样的 AFAIR 代码是 reiserfs 中一个主要错误的来源:
unsigned long num = 1<<63;
If you speak of x86_64, yes, a long is 64 bit and on most other 64 bit linux plytforms too. The problem is that both the 1
and the 63
in your code are simple int
, and so the result is undefined. Better use
如果您谈到 x86_64,是的,long 是 64 位,在大多数其他 64 位 linux plytforms 上也是如此。问题是代码中的the1
和 the63
都是 simple int
,因此结果未定义。更好的使用
unsigned long num = 1UL<<63;
or
或者
unsigned long num = (unsigned long)1<<63;