简体   繁体   English

长型 64bit linux

[英]Long type 64bit linux

Very simple questions guys, but maybe I'm just forgetting something.非常简单的问题伙计们,但也许我只是忘记了一些事情。 In 64bit linux, a long is 8bytes correct?在64bit linux中,一个long是8bytes对吗? If that's the case, and I want to set the 64th bit, I can do the following:如果是这样,并且我想设置第 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.谢谢你。

Actually, if you want some precise length (in bits) for your integers, assuming a C99 conforming 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_tint32_t等类型。一个方便的类型是intptr_t ,一个 integer 类型具有相同的作为void*指针的位数(因此您可以将其称为机器“字”)

In 64bit linux, a long is 8bytes correct?在64bit 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? 什么决定了 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 long type (without sign extension), can I do:另外,如果我想获取long类型的前 32 位(没有符号扩展),我可以这样做:

num = num&0xFFFFFFFF;
or what about:

num = (int)(num);

num = num&0xFFFFFFFF . num = num&0xFFFFFFFF This will give you the lower 32-bits.这将为您提供较低的 32 位。 But note that if long is just 4 bytes on your system then you are getting the entire number .但请注意,如果long在您的系统上只有 4 个字节,那么您得到的是整个数字 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.来到符号扩展部分,如果您使用的是long而不是unsigned long那么您不能取消符号扩展位。 For example, -1 is represented as all ones, right from the 0th bit.例如, -1表示为全 1,从第 0 位开始。 How will you avoid these ones by masking?你将如何通过掩蔽来避免这些?

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 ,编译器可能会发出溢出异常警告

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?:要获得“ low int ”,类似的东西?:

#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;还要注意编译器给出的选项; Ie if you are using gcc:即,如果您使用的是 gcc:

-m32 -m32
-m64 -m64
-mx32 -mx32
Generate code for a 32-bit or 64-bit environment.为 32 位或 64 位环境生成代码。
* The -m32 option sets int, long, and pointer types to 32 bits, and generates code that runs on any i386 system. * -m32 选项将 int、long 和指针类型设置为 32 位,并生成可在任何 i386 系统上运行的代码。
* The -m64 option sets int to 32 bits and long and pointer types to 64 bits, and generates code for the x86-64 architecture. * -m64 选项将 int 设置为 32 位,将 long 和指针类型设置为 64 位,并为 x86-64 架构生成代码。 For Darwin only the -m64 option also turns off the -fno-pic and -mdynamic-no-pic options.仅对于 Darwin,-m64 选项还会关闭 -fno-pic 和 -mdynamic-no-pic 选项。
* The -mx32 option sets int, long, and pointer types to 32 bits, and generates code for the x86-64 architecture. * -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.这仅支持 64 位和 x32 环境。 It is the default address mode for 64-bit environments.它是 64 位环境的默认地址模式。

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.如果你说的是 x86_64,是的,long 是 64 位的,在大多数其他 64 位 linux plytforms 上也是如此。 The problem is that both the 1 and the 63 in your code are simple int , and so the result is undefined.问题是代码中的163都是简单的int ,因此结果是未定义的。 Better use更好用

 unsigned long num = 1UL<<63;

or要么

 unsigned long num = (unsigned long)1<<63;

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”视为 integer,而不是长 integer。直到赋值后才弄明白。

You can fix it by doing:您可以通过执行以下操作来修复它:

unsigned long num = (unsigned long)1<<63;

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM