【问题标题】:What is the value of number left shift by -1 [duplicate]数字左移-1的值是多少[重复]
【发布时间】:2015-10-11 10:35:23
【问题描述】:

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

例如:

23 << -1

【问题讨论】:

  • 左移 -1 看起来像右移 1
  • @adricadar:看起来像(我有时希望是这样),但是:根本错误。
  • 注意:正如OP所说的“数字”,还有一个限制:“每个操作数都应该是整数类型”。
  • @MartinJames:负常数偏移可能来自宏。但更重要的是运行时产生的负偏移,例如在软件浮点算法的规范化过程中。
  • @MartinJames:如果我们关闭所有关于 UB 的问题,我们可以很好地关闭所有 C 问题。少数非 UB 问题是可以接受的“附带损害”。

标签: c operators shift


【解决方案1】:

来自C11标准6.5.7p3(之前的版本基本相同):

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

IOW:undefined behaviour。准备nasal demons

简而言之:不要

警告:虽然许多程序员都意识到这一点并避免负移位计数,但通常会忽略同样计数&gt;= 值的位大小也是未定义的。如果unsigned int 具有32 位或更少,这使得((unsigned int)1 &lt;&lt; 32) - 1 之类的东西实际上是未定义的。对于带符号的值,由于符号而变为more complicated(感谢@chux 指出我)。这是一个常见的陷阱。对于某些实现,常量表达式(编译时评估)和运行时评估可能会出现不同的结果。

【讨论】:

  • 如果int 有32 位或更少,((int)1 &lt;&lt; 31) - 1 是否也未定义?
  • @chux:已更新。谢谢!
【解决方案2】:

C 中的按位左移运算符:

  1. 数据的位模式可以左移指定数量的位置
  2. 当数据左移时,尾随零用零填充。
  3. 左移运算符是二元运算符 [Bi - two]
  4. 二进制表示,需要两个参数的运算符!

语法:

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

如果 Number of Places 变为负数,它将是未定义的

【讨论】:

    【解决方案3】:

    正如奥拉夫在回答中所说,左移一个负数是未定义的。

    事实上,如果你尝试向任一方向移动负数,gcc 会发出警告。

    【讨论】:

    • "... gcc 会给出警告 ...": 但前提是它可以检测到它的编译时间,即如果移位计数是问题中的常量。
    猜你喜欢
    • 2015-12-16
    • 2023-02-16
    • 2011-02-22
    • 2014-05-15
    • 2010-11-06
    • 1970-01-01
    • 1970-01-01
    • 2019-12-07
    • 1970-01-01
    相关资源
    最近更新 更多