【问题标题】:Does bit-shifting in C only work on blocks of 32-bitsC 中的位移是否仅适用于 32 位块
【发布时间】:2021-08-22 07:03:18
【问题描述】:

在一段时间没有编码后,我再次尝试使用 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 位,而我希望它位于第 49 位一个 64 位的寄存器。

我对@9​​87654332@ 类型进行了同样的尝试,结果是一样的。

我试过编译有和没有m64 参数,都一样。

【问题讨论】:

标签: c bit-manipulation 32bit-64bit bit-shift


【解决方案1】:

在您的设置中,常量 1 是一个 32 位整数。因此,表达式1 &lt;&lt; testBin 在 32 位上运行。您需要使用 64 位常量来使表达式在 64 位上运行,例如:

x = (uint64_t)1 << testBin;

这并没有改变这样一个事实,即移位 240 位是形式上未定义的行为(即使它可能无论如何都会给出预期的结果)。如果将testBin 设置为48,则结果将是明确定义的。因此,应首选以下内容:

x = (uint64_t)1 << (testBin % 64);

【讨论】:

  • 只需使用1ULL。无需投射
  • @phuclv 有可能,是的。我想说这主要是品味/背景问题。 unsigned long long 被指定为至少 64 位,但可能更多。在我看来,在这种情况下,显式转换为 64 位整数更清晰,因为这是 OP 使用的类型。
【解决方案2】:

这是因为如果常量1 的默认整数类型。它是整数(不是 long long 整数)。你需要使用 ULL 后缀

x = 1ULL << testbin

PS 如果你想移动 240 位并且你的整数小于它(也许你的实现支持一些巨大的整数),这是一个未定义的行为)

【讨论】:

    猜你喜欢
    • 2020-06-19
    • 2022-01-18
    • 1970-01-01
    • 2012-11-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-10-21
    相关资源
    最近更新 更多