【问题标题】:Why doesn't C have rotate left/right operators? [closed]为什么 C 没有左/右旋转运算符? [关闭]
【发布时间】:2012-10-27 10:39:37
【问题描述】:

我想这是一个哲学问题。

C 语言具有标准的按位运算集,包括OR、AND、XOR、SHIFT LEFT/RIGHT 和NOT。为什么语言中不包含向左/向右旋转运算符或函数?

这些运算符与其他按位运算符具有相同的复杂性,并且与其他运算符一样,通常需要一条汇编指令。此外,我可以想到旋转运算符的很多用途,可能不少于,例如,xor 运算符 - 所以我觉得它们没有与其他运算符一起包含在 C 中,这听起来有点奇怪。

如果您确实需要在 C 或 C++ 中旋转,there's a separate FAQ question about best-practices for it。对此问题的讨论与此无关。

【问题讨论】:

  • @Cthulhu 我知道这一点,甚至在问题正文中写下了这一点。问题是关于 C
  • 因为它被遗忘了? ;-) 我喜欢这些:stackoverflow.com/a/12733007/694576
  • 我想这可能是因为您有时不能完全确定 C 中不同数据类型的大小。旋转在 64 位整数中的表现与在 32 位整数中的表现不同位一。 (我知道这也适用于轮班,轮班时会更明显)。
  • @Cthulhu 或者您可以只使用移位和 OR,每个理智的编译器都会检测到该模式,并且与内联 asm 不同,它不会抑制优化。

标签: c bitwise-operators


【解决方案1】:

我认为这是因为有两种类型的旋转:带进位和不带进位,这使得根据生成的机器的 CARRY 标志(1 或 0)进行不同的旋转。这意味着总共要实现 4 个运算符,从而使语言变得不必要地复杂,前提是可以像 @Aniket 所示的那样简单地实现旋转。

编辑:

不过,移位也可以有符号和无符号进行。实际上 Javascript 有两个运算符,AFAIK。但是,由于 C 支持有符号和无符号变量,我认为执行有符号移位是没有意义的,因为编译器应该知道我们是在移位有符号变量还是无符号变量。有符号/无符号移位对于算术计算很有用,C 编译器可以使用它们来生成汇编代码。例如,许多算术运算(例如乘以或除以 2 的幂)被编译器转换为移位运算。我们在 C 中使用移位运算符的唯一原因是使用位掩码。

【讨论】:

  • @Claudix 我主要指的是没有进位的旋转运算符,但很好。无论如何,xor 也不是必需的,因为它可以与其他运算符一起实现。
  • 是的,但是 xor 是一个明确的运算符。谁知道呢,也许 C 的维护者注意到没有明确的主导惯例来说明应该如何进行轮换 :-)
  • @icepack 那么大多数其他运算符也不需要。我们可以只有 1 个运算符(NAND)并以这种方式实现所有布尔逻辑
  • simply?! ...它是一个词...但实际上并不是那么简单
【解决方案2】:

C 没有用于二进制的左旋转和右旋转。您可以自己编写左旋转和右旋转功能。但按照标准:不。

简单的向左旋转:

int rotate_left(int num, int bits)
{
  return ((num << bits) | (num >> (32 -bits)));
} 

int rotate_right(int num, int bits)
{
  return ((num >> bits) | (num << (32 -bits)));
}

上述函数仅适用于 32 位整数 :)

现在谈谈哲学:C 旨在尽可能地可移植。这就是标准团队希望它成为“便携式汇编器”的原因。不能保证 rol 和 ror 存在于未来的架构中。或者可能表现不同。因此,它远离标准。

【讨论】:

  • 好.. 最好把它改成宏
  • 好,但实际问题是Anyone has an idea why rotate left/rotate right isn't included in the language?
  • @memosdp 是的,发布后编辑
  • @GrijeshChauhan:不!
  • 该代码中潜伏着很多未定义的行为,左移负整数是 UB,如果 value * 2^shift 在类型中不可表示,则非负值的有符号整数的左移是 UB .负整数的右移是实现定义的,并且通常会进行符号扩展,因此它们实际上不会旋转。让它们对无符号整数进行操作,你唯一的问题变成了移位距离必须是非负的并且小于类型宽度的约束(bits &amp;= 31,如果bits == 0,则返回 num)。
猜你喜欢
  • 2013-01-15
  • 1970-01-01
  • 1970-01-01
  • 2016-06-30
  • 2010-10-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多