C 中的位移位仅适用于 32 位块

问题描述

在一段时间没有编码之后,我再次尝试使用 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 返回 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 位并且你的整数小于它(也许你的实现支持一些巨大的整数),这是一个未定义的行为)

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...