转到<<和>>运算符


Answers:


168

超级(可能超过)简化定义仅<<用于“时间2”,并且>>并且用于“除以2”,其后的数字是多少次。

因此n << x,“ n乘以2,x乘以”。和y >> z是“ y除以2,z倍”。

例如,1 << 5是“ 1 32 >> 5乘2、5乘”或32。并且是“ 32除以2、5乘”或1。

所有其他答案都给出了更多的技术定义,但没人能直截了当地提出来,我认为您可能想要这样。


7
这是一个很好的答案。谢谢,这真的使它在我脑海中固化了。
山姆·奥罗佐

2
这就是答案。
Utsav Gupta

103

根据http://golang.org/doc/go_spec.html上的规范,似乎至少对于整数来说,这是一个二进制移位。例如,二进制0b00001000 >> 1将是0b00000100,而0b00001000 << 1将是0b00010000。


Go显然不接受二进制整数的0b表示法。我只是将其用作示例。在十进制中,8 >> 1为4,而8 << 1为16。向左移一位等于乘以2,向右移一位等于除以2,则舍去任何余数。


4
好答案。这使得很多的感觉,当我认为我是在代码交易与2(1 <<功率= 2 ^功率)的权力见状
斯蒂芬·史密斯

6
我认为这将是完整的等式:(x << n == x * 2 ^ n)(x >> n == x * 2 ^(-n))
MondayPaper

很好的答案,我一开始二进制转换似乎很麻烦,但是将数值转换为带有2的幂的十进制有助于很好地获得它
minhajul

31

<<和>>运算符是Go算术运算符

<<   left shift             integer << unsigned integer
>>   right shift            integer >> unsigned integer

移位运算符将左操作数移位由右操作数指定的移位计数。如果左操作数是有符号整数,则执行算术移位;如果左操作数是无符号整数,则执行逻辑移位。移位计数必须是无符号整数。班次计数没有上限。移位的行为就好像左操作数被n移位了n次,移位次数为n。结果,x << 1与x * 2相同,并且x >> 1与x / 2相同,但被截断为负无穷大。


10

它们基本上是算术运算符,在其他语言中的含义相同,这里是基本的PHP,C,Go示例

package main

import (
    "fmt"
)

func main() {
    var t , i uint
    t , i = 1 , 1

    for i = 1 ; i < 10 ; i++ {
        fmt.Printf("%d << %d = %d \n", t , i , t<<i)
    }


    fmt.Println()

    t = 512
    for i = 1 ; i < 10 ; i++ {
        fmt.Printf("%d >> %d = %d \n", t , i , t>>i)
    }

}

GO演示

C

#include <stdio.h>
int main()
{

    int t = 1 ;
    int i = 1 ;

    for(i = 1; i < 10; i++) {
        printf("%d << %d = %d \n", t, i, t << i);
    }

        printf("\n");

    t = 512;

    for(i = 1; i < 10; i++) {
        printf("%d >> %d = %d \n", t, i, t >> i);
    }    

  return 0;
}

C演示

的PHP

$t = $i = 1;

for($i = 1; $i < 10; $i++) {
    printf("%d << %d = %d \n", $t, $i, $t << $i);
}

print PHP_EOL;

$t = 512;

for($i = 1; $i < 10; $i++) {
    printf("%d >> %d = %d \n", $t, $i, $t >> $i);
}

PHP演示

他们都会输出

1 << 1 = 2 
1 << 2 = 4 
1 << 3 = 8 
1 << 4 = 16 
1 << 5 = 32 
1 << 6 = 64 
1 << 7 = 128 
1 << 8 = 256 
1 << 9 = 512 

512 >> 1 = 256 
512 >> 2 = 128 
512 >> 3 = 64 
512 >> 4 = 32 
512 >> 5 = 16 
512 >> 6 = 8 
512 >> 7 = 4 
512 >> 8 = 2 
512 >> 9 = 1 

7

Go的<<和>>与其他语言中的移位类似(即,除法或乘以2的幂),但是因为Go是比C / C ++更安全的语言,所以当移位计数为数字时,它会做一些额外的工作。

x86 CPU中的移位指令仅考虑移位计数的5位(64位x86 CPU中为6位)。在C / C ++之类的语言中,移位运算符可转换为一条CPU指令。

下面的Go代码

x := 10
y := uint(1025)  // A big shift count
println(x >> y)
println(x << y)

版画

0
0

而C / C ++程序会打印

5
20

3
对于C和C ++移位运算符,“如果右操作数为负,或者大于或等于提升后的左操作数的位长度,则该行为是不确定的。” C和C ++标准不保证C和C ++程序将打印5和20
peterSO

@peterSO:是的,您是对的。我的观点是,每种编程语言标准都必须在具体的CPU上有具体的实现。在单个CPU系列(x86-32)的上下文中,所有C / C ++编译器的行为都是(可以预期)相同。这样做的原因是,当上下文没有告诉用户有关“ x”和“ y”的任何信息时,发出恰好1条SHL / SHR / etc指令来实现移位运算符是优化C / C ++编译器可以做的最好的事情。并且,如果编译器知道代码具有未定义行为的事实,则应将其告知用户。

2
我不同意。您应该编写可移植的代码。Linux和Windows均在ARM上运行。专注于单个CPU系列是短视的。此外,y是一个变量。实际上,编译器不了解其实际运行时值。
peterSO 2011年

@Atom除了绝对不能保证会发生什么的语言外,即使在具有单个编译器的单台计算机上,例如,如果您更改编译选项(例如,优化的构建),未定义的行为也可能会发生变化。以任何方式依赖它都是危险的错误IMO。
保罗·汉金

@Anonymous是的,但这只是理论。你能提供一个具体的例子,其中改变编译选项导致不同的行为,<<>>在C / C ++?

6

<<左移。 >>当左操作数是一个有符号整数时,是右扩展的符号;当左操作数是一个无符号整数时,它是右扩展的零。

为了更好地理解>>想到的

var u uint32 = 0x80000000;
var i int32 = -2;

u >> 1;  // Is 0x40000000 similar to >>> in Java
i >> 1;  // Is -1 similar to >> in Java

因此,当应用于无符号整数时,左侧的位填充为零,而应用于有符号整数时,左侧的位填充为最左边的位(当有符号整数按2的整数表示负数时,该位为1补充)。


3

十进制数学中,当我们乘以10或除以10时,会在数字末尾产生零。

二进制中2具有相同的作用。因此,我们在末尾添加零,或删除最后一位

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.