长型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

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

Long type 64bit linux

clinuxbit-manipulation

提问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 longis just 4 bytes on your system then you are getting the entire number. Coming to the sign extension part, if you've used a longand not unsigned longthen you cannot do away with the sign extended bits. For example, -1is 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 numdoes 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_tetc. 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_tint32_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=longetc.

还有-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 1and the 63in 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;