移位运算符(<<>>)在C中是算术还是逻辑?

时间:2008-08-11 08:55:13

标签: c binary bit-manipulation bit-shift

在C中,移位运算符(<<>>)是算术还是逻辑?

10 个答案:

答案 0 :(得分:122)

向左移动时,算术和逻辑移位之间没有区别。向右移动时,移位类型取决于要移位的值的类型。

(作为那些不熟悉差异的读者的背景,1位的“逻辑”右移将所有位向右移动,并用0填充最左边的位。“算术”移位保留原始值最左边的位。当处理负数时,差异变得很重要。)

当移动无符号值时,&gt;&gt; C中的运算符是逻辑移位。当移动有符号值时,&gt;&gt;运算符是算术移位。

例如,假设一台32位机器:

signed int x1 = 5;
assert((x1 >> 1) == 2);
signed int x2 = -5;
assert((x2 >> 1) == -3);
unsigned int x3 = (unsigned int)-5;
assert((x3 >> 1) == 0x7FFFFFFD);

答案 1 :(得分:90)

根据K&R 2nd edition,结果与实施有关,适用于有符号值的右移。

Wikipedia说C / C ++'通常'对签名值实施算术移位。

基本上你需要测试你的编译器或不依赖它。我对当前MS C ++编译器的VS2008帮助表明他们的编译器进行了算术移位。

答案 2 :(得分:16)

就你所获得的班次类型而言,重要的是你正在转移的价值类型。一个典型的错误来源是当你将文字移动到比如掩盖位时。例如,如果你想删除无符号整数的最左边的位,那么你可以尝试这个作为你的掩码:

~0 >> 1

不幸的是,这会让你遇到麻烦,因为掩码将设置其所有位,因为被移位的值(~0)被签名,因此执行算术移位。相反,您希望通过明确地将值声明为无符号来强制进行逻辑移位,即通过执行以下操作:

~0U >> 1;

答案 3 :(得分:15)

这里有保证C中逻辑右移和算术右移的函数:

int logicalRightShift(int x, int n) {
    return (unsigned)x >> n;
}
int arithmeticRightShift(int x, int n) {
    if (x < 0 && n > 0)
        return x >> n | ~(~0U >> n);
    else
        return x >> n;
}

答案 4 :(得分:6)

当你这样做的时候   - 左移1乘以2   - 右移1除以2

 x = 5
 x >> 1
 x = 2 ( x=5/2)

 x = 5
 x << 1
 x = 10 (x=5*2)

答案 5 :(得分:4)

好吧,我看了it up on wikipedia,他们有话要说:

  然而,C只有一个右移   运算符,&gt;&gt;。许多C编译器选择   哪个权利转移到依赖   在什么类型的整数   转移;经常签名整数   使用算术移位移位,   和无符号整数被移位   使用逻辑转移。

所以听起来这取决于你的编译器。同样在那篇文章中,请注意左移与算术和逻辑相同。我建议在边框情况下使用一些有符号和无符号数字进行简单测试(当然是高位集)并查看编译器的结果。我还建议避免依赖它是一个或另一个,因为看起来C没有标准,至少如果它是合理的并且可能避免这种依赖。

答案 6 :(得分:0)

通常会对无符号变量使用逻辑移位,对已签名变量使用左移。算术右移是真正重要的,因为它将签署扩展变量。

将在适用时使用此功能,因为其他编译器可能会这样做。

答案 7 :(得分:0)

左移<<

这在某种程度上很简单,无论何时使用移位运算符,它总是一个按位操作,因此我们不能使用double和float操作。每当我们将shift移一个零时,它总是被添加到最低有效位(LSB)。

但是在右移>>中,我们必须遵循一个额外的规则,并且该规则被称为&#34;签署位副本&#34;。 &#34;符号位副本&#34;的含义如果设置了最高有效位(MSB),那么在再次右移之后,MSB将被设置,如果它被重置,那么它再次被重置,意味着先前的值是否为零然后在移位之后再次,如果前一位为1则该位为零,然后在移位后它再次为1。此规则不适用于左移。

右移的最重要的例子,如果你将任何负数移到右移,然后在一些移位之后最终达到零,然后在此之后如果移动这个-1任何次数值将保持相同。请检查。

答案 8 :(得分:0)

GCC确实

  1. for -ve - &gt;算术转移

  2. for + ve - &gt;逻辑转变

答案 9 :(得分:-6)

根据许多编译器:

  1. <<是算术左移或按位左移。
  2. >>是算术右移位器按位右移。