【问题标题】:Why (-7 << 16) | 75 has some extra bits?为什么 (-7 << 16) | 75有一些额外的位?
【发布时间】:2021-01-31 12:32:41
【问题描述】:

我有一个问题是在数字中设置了一些额外的位:

void print2_helper(int x) {
  int isodd = x%2 != 0;
  x /= 2;
  if (x)
    print2_helper(x);
  putchar('0' + isodd);
}
printf("-7 << 16: ");
print2_helper((-7 << 16));

printf("\n(-7 << 16) | 75: ");
print2_helper((-7 << 16) | 75);
puts("\n");

输出:

-7 << 16: 1110000000000000000
(-7 << 16) | 75: 1101111111110110101

为什么简单的 |75 会产生如此奇怪的数字?

【问题讨论】:

  • port70.net/~nsz/c/c11/n1570.html#6.5.7p4 左移负数在技术上是未定义的行为(您应该使用无符号数进行算术运算)但我想这里的主要问题是为什么打印机的参数是 int x 和不是unsigned x?
  • 19 位整数 - 有趣
  • @PSkocikis 从技术上讲,这是一种非常明确的行为
  • print2_helper 没有为负数打印正确的位表示。 -7
  • @PSkocik 你自己的回答证明你不正确。

标签: c binary bit negative-number


【解决方案1】:

(-7 &lt;&lt; 16) | 75 产生一个负值,而 print2_helper 在负值上不能正常工作,正如其他人指出的那样。

x /= 2 不等于在负整数上右移。 让我们来看看x=-3 的结果如何(为了简洁起见,我们使用 5 位整数)

11101 = -3

-3 / 2 = -1

-1 在二进制表示中是 11111,这不是预期的结果 (01110)。

print2_helper 上使用无符号整数参数应该可以解决问题。 (连同修复cmets中已经提到的PSKocik问题,可以通过添加u后缀使其成为无符号整数:(-7u &lt;&lt; 16) | 75

【讨论】:

  • 可以通过添加 u 后缀使其成为无符号整数来完成:(-7u 嗯?你认为-7u 的评价是什么? (提示:以unary minus operator开头)
  • 在这种情况下,unsigned integer 没有整数提升,因为它的一元运算符。见整数提升规则:enseignement.polytechnique.fr/informatique/INF478/docs/Cpp/en/c/…
  • 整数提升无关紧要。 "An integer constant begins with a digit ..." 没有负整数常量。 -7u 不是一个标记 - 它是正值 7u 被一元减号运算符否定 - 所以它是一个有符号整数值。
  • 如果不存在整数提升,则结果类型不会改变,如您的“提示”链接中所述:... The integer promotions are performed on the operand, and the result has the promoted type. 因此,它会导致无符号类型。
  • 另外,请参阅 clang 的 AST:godbolt.org/z/b9ndzE 如果它会导致有符号整数类型,它会在返回之前插入隐式转换为无符号。
猜你喜欢
  • 2022-01-09
  • 2014-03-22
  • 1970-01-01
  • 2018-07-23
  • 1970-01-01
  • 2012-11-16
  • 1970-01-01
  • 2019-07-18
  • 1970-01-01
相关资源
最近更新 更多