6

非常简单的问题,但也许我只是忘记了一些东西。在 64bit linux 中,long 是 8bytes 吗?如果是这种情况,并且我想设置第 64 位,我可以执行以下操作:

unsigned long num = 1<<63;

然而,每当我编译它时,它都会给我一个错误,说我左移的幅度超过了宽度。另外,如果我想采用 long 类型的前 32 位(没有符号扩展),我可以这样做:

num = num&0xFFFFFFFF;

或者怎么样:

num = (int)(num);

谢谢你。

4

5 回答 5

4

实际上,如果您想要整数的精确长度(以位为单位),假设一个符合C99的编译器,#include <stdint.h>并使用诸如 等类型int64_tint32_t 一个方便的类型是,一个与指针intptr_t具有相同位数的整数类型(因此您可以调用void*它是一个机器“词”)

于 2012-04-06T07:22:08.307 回答
4

在 64bit linux 中,long 是 8bytes 吗?

不必。取决于编译器而不是底层操作系统。检查这个以获得很好的讨论。 什么决定整数的大小?

然而,每当我编译这个时,它都会给我一个错误,说我左移超过了宽度

这个大家都已经回答过了。采用1UL

另外,如果我想采用long类型的前 32 位(没有符号扩展),我可以这样做:

num = num&0xFFFFFFFF;
or what about:

num = (int)(num);

num = num&0xFFFFFFFF. 这将为您提供较低的 32 位。但请注意,如果long您的系统上只有 4 个字节,那么您将获得整个数字。来到符号扩展部分,如果你使用了 along而不是,unsigned long那么你就不能取消符号扩展位。例如,-1从第 0 位开始,全部表示为 1。您将如何通过掩蔽来避免这些问题?

num = (int)(num)将为您提供较低的 32 位,但如果num不适合编译器,编译器可能会通过溢出异常警告int

于 2012-04-06T09:49:11.807 回答
1

为了便携性,您可以使用:

限制.h

#define LNG_BIT   (sizeof(long) * CHAR_BIT)

unsigned long num = 1UL << (LNG_BIT - 1);

要获得“低 int ”,例如?:

#define INT_BIT   (sizeof(int) * CHAR_BIT)

if (LNG_BIT > INT_BIT)
    return num & (~0UL >> INT_BIT);
else
    return num;

或者

    num &= ~(~0U << INT_BIT);

或者,使用掩码等。很大程度上取决于您想要 int 位的原因、用途等。

还要注意编译器给出的选项;即,如果您使用的是 gcc:

-m32
-m64
-mx32
        为 32 位或 64 位环境生成代码。
        * -m32 选项将 int、long 和指针类型设置为 32 位,并生成可在任何 i386 系统上运行的代码。
        * -m64 选项将 int 设置为 32 位,将 long 和指针类型设置为 64 位,并为 x86-64 架构生成代码。对于 Darwin,只有 -m64 选项也会关闭 -fno-pic 和 -mdynamic-no-pic 选项。
        * -mx32 选项将 int、long 和指针类型设置为 32 位,并为 x86-64 架构生成代码。

还有-maddress-mode=long等等。

-maddress-mode=long
        为长地址模式生成代码。这仅支持 64 位和 x32 环境。它是 64 位环境的默认地址模式。

于 2012-04-06T09:19:13.777 回答
0

我认为第一个问题的问题在于编译器将“1”视为整数,而不是长整数。直到分配之后才弄明白。

您可以通过以下方式修复它:

unsigned long num = (unsigned long)1<<63;
于 2012-04-06T06:53:58.920 回答
0

像这样的 AFAIR 代码是几年前 reiserfs 中一个主要错误的来源:

unsigned long num = 1<<63;

如果您谈到 x86_64,是的,long 是 64 位的,并且在大多数其他 64 位 linux plytforms 上也是如此。问题是代码中的 the1和 the63都很简单int,因此结果是未定义的。更好的使用

 unsigned long num = 1UL<<63;

或者

 unsigned long num = (unsigned long)1<<63;
于 2012-04-07T18:58:32.720 回答