数字左移-1的值是多少?

11

使用C编程中的左移运算符,将数字左移-1位时的结果是什么?

例如:

23 << -1

2
左移一位并取反,看起来就像右移一位。 - adricadar
@adricadar:看起来像(有时我也希望是这样),但根本就错了。 - too honest for this site
注意:由于OP说了“数字”,还有另一个限制:“每个操作数都必须具有整数类型”。 - chux - Reinstate Monica
1
@MartinJames:负常量移位可能来自宏。但更重要的是,运行时产生的负移位,例如在软件浮点算术规范化过程中。 - too honest for this site
1
@MartinJames:如果我们关闭所有关于未定义行为的问题,我们很可能会关闭所有C语言的问题。少数非UB问题将被视为可以接受的“附带损失”。 - too honest for this site
显示剩余5条评论
3个回答

9

根据C11标准6.5.7p3(对于早期版本基本相同):

“如果右操作数的值为负或大于等于提升后的左操作数的宽度,则行为未定义。”

换句话说:未定义的行为。准备好迎接鼻妖

简而言之:不要

注意:虽然许多程序员都知道并避免负移位计数,但往往忽略了也会出现计数>=值的位大小未定义的情况。如果unsigned int具有32位或更少位,则这使得像((unsigned int)1 << 32) - 1这样的东西实际上是未定义的。对于带符号值,由于符号的原因,事情变得更加复杂(感谢@chux指出)。这是一个常见的陷阱。对于某些实现,可能会发生常量表达式(编译时评估)和运行时评估的不同结果。

1
如果int类型只有32位或更少,那么((int)1 << 31) - 1也是未定义的吗? - chux - Reinstate Monica
@chux:已更新。谢谢! - too honest for this site

1
如Olaf在他的回答中所说,左移负数是未定义的。
事实上,如果您尝试通过负数向任一方向进行移位,gcc会发出警告。

3
如果在编译时,即像问题中一样移位次数是一个常量,那么gcc会发出警告,但只有在能够检测到的情况下。 - too honest for this site

0

C 中的按位左移运算符:

  1. 数据的二进制模式可以左移指定数量的位置
  2. 当数据向左移动时,尾部零会被填充为 0。
  3. 左移运算符是一个二元运算符 [Bi - 两个]
  4. 二进制意味着需要两个参数的运算符!

Table

语法:

**[variable]<<[number of places]**

如果位置数变为负数,它将变为未定义。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接