web-dev-qa-db-ja.com

移動<<および>>演算子

Goで<<>>の使用方法を誰かに説明していただけますか?他のいくつかの言語に似ていると思います。

94
brianoh

スーパー(おそらくオーバー)の単純化された定義は、単に<<は「times 2」と>>は「2で割る」ことを意味し、その後の数字は何回目です。

そう n << xは「n倍2、x倍」です。そして、y >> zは「yを2で割ったz倍」です。

例えば、 1 << 5は「1回2、5回」または32です。そして32 >> 5は、「32÷2、5回」または1です。

他のすべての答えはより技術的な定義を与えますが、誰もそれを本当に率直に言って誰もそれを望んでいないと思いました。

105
Peter

http://golang.org/doc/go_spec.html の仕様から、少なくとも整数では、バイナリシフトであるように思われます。たとえば、バイナリ0b00001000 >> 1は0b00000100になり、0b00001000 << 1は0b00010000になります。


Goは、バイナリ整数の0b表記を受け入れないようです。例として使用していました。 10進数では、8 >> 1は4で、8 << 1は16です。1だけ左にシフトすることは2を乗算することと同じであり、1だけ右にシフトすることは2で除算することと同じです。

87
jcomeau_ictx

<<および>>演算子は Go算術演算子 です。

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

シフト演算子は、右のオペランドで指定されたシフト数だけ左のオペランドをシフトします。左オペランドが符号付き整数の場合は算術シフトを実装し、符号なし整数の場合は論理シフトを実装します。シフト数は符号なし整数でなければなりません。シフト数に上限はありません。シフトは、左のオペランドがnのシフトカウントに対して1回n回シフトされるかのように動作します。その結果、x << 1はx * 2と同じで、x >> 1はx/2と同じですが、負の無限大に向かって切り捨てられます。

29
peterSO

基本的には 算術演算子 であり、他の言語でも同じですPHP、C、Go Example

[〜#〜] 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 
9
Baba

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
7
user811773

<<は左シフトです。 >>は、左オペランドが符号付き整数の場合は符号拡張右シフトであり、左オペランドが符号なし整数の場合はゼロ拡張右シフトです。

>> のことを考える

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です)補体)。

6
Mike Samuel

10進数の数学で、10で乗算または除算の場合、数値の末尾にゼロを設定します。

binaryでは、2は同じ効果があります。したがって、最後にゼロを追加するか、最後の桁を削除します

2
robert king