c - 理解太小类型的移位操作

标签 c bit-manipulation bit-shift

我的代码在 C 中有一个按位移位的问题,我归结为以下示例:

#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include <inttypes.h>

int main(int argc, char **argv)
{
  char a = 1;
  int i=0;
  uint64_t b;
  for(i=0; i<64; i++)
  {
    b=0;
    printf("i=%d\n", i);
    b = (a<< ((uint64_t) i));
    printf("%" PRIu64 "\n", b);
  }
  return 0;

}

由于在此 MWE 中不明显的原因,a 是一个 char,我想从中生成 2 的幂,直到 2^63。它失败了,因为发生了一些奇怪的事情,因为 a 不是 uint64_t。明显的修复是

b = ((uint64_t)a<< ((uint64_t) i))

为了理解到底发生了什么,我写了上面的 MWE 示例,我从中获得了输出(部分显示):

i=30  
1073741824  
i=31  
18446744071562067968  
i=32  
1  
i=33  
2  

现在我想知道如何解释从 i=30i=31 的跳转?它是如何在 i=32 处再次变为 1 的?

如果有兴趣,我用gcc (gcc (SUSE Linux) 4.8.5)编译了上面的代码

最佳答案

此处出现的(有点出乎意料的)规则是,当涉及到 << 时,

the type of the result is that of the promoted left operand

这意味着 a << (uint64_t) i 的类型是一个 int , 作为 char输入 a自动加宽为 int .

看来您的 int是一个 32 位 2 的补码类型。因此对于 i大于或等于 31,表达式的行为是未定义

关于c - 理解太小类型的移位操作,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48542911/

相关文章:

java - HashMap.tableSizeFor(...)。这段代码如何舍入到下一个 2 的幂?

c++ - C位运算题

c++ - 使用混合 C/C++ header 在 C 中使用 C++ 对象

SQL 按位掩码

C++ 快速高效地对 40 字节数组执行 bit_count 和 AND 运算

c++ - 在位数组中找到 N 个 1 位的字符串

c - 右移运算符无限循环

c - 用 C 语言逐行读取文件

c - C 中 Infix-to-Postfix 程序的操作数之间的间距

java - RGB 24 位到 RGB 8 位位移