C 中的位移是不是仅适用于 32 位块
Posted
技术标签:
【中文标题】C 中的位移是不是仅适用于 32 位块【英文标题】: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 位的寄存器。
我对@987654332@ 类型进行了同样的尝试,结果是一样的。
我试过编译有和没有m64
参数,都一样。
【问题讨论】:
欺骗Unexpected C/C++ bitwise shift operators outcome 或任何其他关于左移 >= 类型宽度的内容。我不明白你为什么期望移动 240 个位置来做任何有意义或可预测的事情。 您在代码中有两个问题:首先,1 << testBin
在您的 C 实现中可能是 32 位的 int
上运行,因为它使用 1
的类型,即 @ 987654337@,而不是分配给这个表达式的类型,uint64_t
。其次,C 标准定义<<
仅用于小于左操作数类型宽度的移位,对于int
或uint64_t
来说,240 太大了。您想要的正确表达式将设置左操作数的类型并以宽度为模减小右操作数,因此(uint64_t) 1 << testBin % 64;
。
@underscore_d:这不是重复的,因为这个问题只回答了这里的两个问题之一。
第一个问题的重复:Why does shifting 0xff left by 24 bits result in an incorrect value?,Why does 1ul << 64 return 1 instead of 0?,Bitwise shift operation in C on uint64_t variable,C left shift on 64 bits fail
第二个问题的重复:What does the C standard say about bitshifting more bits than the width of type?,When can bit shifting cause undefined behaviour,Shifting unsigned int more than the size of it, undefined or not?
【参考方案1】:
在您的设置中,常量 1
是一个 32 位整数。因此,表达式1 << 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 位并且你的整数小于它(也许你的实现支持一些巨大的整数),这是一个未定义的行为)
【讨论】:
以上是关于C 中的位移是不是仅适用于 32 位块的主要内容,如果未能解决你的问题,请参考以下文章
C++ memset 是不是仅适用于 0 和 -1? [关闭]
UIScrollView 是不是仅适用于嵌入在导航控件中的视图控制器?
来自 JBoss - RedHat codeready 的基于 Eclipse 的图形 Camel 编辑器是不是仅适用于 xml 中的骆驼?
相同的逻辑适用于c ++,但不适用于python以获得堆栈中的最大值,我的代码中是不是缺少某些东西