C 中的位移是否仅适用于 32 位块
Does bit-shifting in C only work on blocks of 32-bits
在一段时间不编码之后,我再次尝试使用 C,并且遇到了一些我不理解的关于位移的事情。
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
void main()
{
uint64_t x = 0;
uint64_t testBin = 0b11110000;
x = 1 << testBin;
printf("testBin is %"PRIu64"\nx is %"PRIu64"\n", testBin, x);
//uint64_t y = 240%32;
//printf("%"PRIu64 "\n",y);
}
在上面的代码中,x
returns 65536,表示在移位240位后,1
现在位于32位寄存器的第17位,而我希望它位于 64 位寄存器的第 49 位。
我对 unsigned long long
类型进行了同样的尝试,效果相同。
我试过使用和不使用 m64
参数进行编译,两者都是一样的。
在您的设置中,常量 1
是一个 32 位整数。因此表达式 1 << testBin
在 32 位上运行。您需要使用 64 位常量才能使表达式在 64 位上运行,例如:
x = (uint64_t)1 << testBin;
这不会改变这样一个事实,即移动 240 位在形式上是未定义的行为(尽管它可能无论如何都会给出预期的结果)。如果 testBin
设置为 48
,结果将是明确定义的。因此,应首选以下内容:
x = (uint64_t)1 << (testBin % 64);
发生这种情况是因为如果常量的默认整数类型1
。它是整数(不是长整数)。你需要使用 ULL 后缀
x = 1ULL << testbin
PS 如果你想移动 240 位并且你的整数小于它(也许你的实现支持一些巨大的整数),这是一个未定义的行为)
在一段时间不编码之后,我再次尝试使用 C,并且遇到了一些我不理解的关于位移的事情。
#include <stdio.h>
#include <stdint.h>
#include <inttypes.h>
void main()
{
uint64_t x = 0;
uint64_t testBin = 0b11110000;
x = 1 << testBin;
printf("testBin is %"PRIu64"\nx is %"PRIu64"\n", testBin, x);
//uint64_t y = 240%32;
//printf("%"PRIu64 "\n",y);
}
在上面的代码中,x
returns 65536,表示在移位240位后,1
现在位于32位寄存器的第17位,而我希望它位于 64 位寄存器的第 49 位。
我对 unsigned long long
类型进行了同样的尝试,效果相同。
我试过使用和不使用 m64
参数进行编译,两者都是一样的。
在您的设置中,常量 1
是一个 32 位整数。因此表达式 1 << testBin
在 32 位上运行。您需要使用 64 位常量才能使表达式在 64 位上运行,例如:
x = (uint64_t)1 << testBin;
这不会改变这样一个事实,即移动 240 位在形式上是未定义的行为(尽管它可能无论如何都会给出预期的结果)。如果 testBin
设置为 48
,结果将是明确定义的。因此,应首选以下内容:
x = (uint64_t)1 << (testBin % 64);
发生这种情况是因为如果常量的默认整数类型1
。它是整数(不是长整数)。你需要使用 ULL 后缀
x = 1ULL << testbin
PS 如果你想移动 240 位并且你的整数小于它(也许你的实现支持一些巨大的整数),这是一个未定义的行为)