回答:
スーパー(おそらくオーバー)の単純化された定義は<<
、「2倍」と>>
「2で除算」に使用されるもので、その後の数は何回かです。
そうn << x
です、「n回2、回×」。そしてy >> z
、「yを2で割ったz回」です。
たとえば、1 << 5
「1倍2、5倍」または32です。また32 >> 5
、「32を2で割って5倍」または1です。
他のすべての答えはより技術的な定義を提供しますが、誰もそれを本当に率直に説明した人はいません。
http://golang.org/doc/go_spec.htmlの仕様から、少なくとも整数では、バイナリシフトであるようです。たとえば、バイナリ0b00001000 >> 1は0b00000100、0b00001000 << 1は0b00010000になります。
Goは明らかに2進整数の0b表記を受け入れません。例として使用しただけです。10進数では、8 >> 1は4、8 << 1は16です。左に1シフトすることは2を乗算することと同じで、右に1シフトすることは2で除算することと同じで、残りはすべて破棄されます。
<<および>>演算子はGo算術演算子です。
<< left shift integer << unsigned integer
>> right shift integer >> unsigned integer
シフト演算子は、右のオペランドで指定されたシフト数だけ左のオペランドをシフトします。左のオペランドが符号付き整数の場合は算術シフトを実装し、符号なし整数の場合は論理シフトを実装します。シフト数は符号なし整数でなければなりません。シフト数に上限はありません。シフトは、シフトカウントがnの場合、左のオペランドが1だけn回シフトされるかのように動作します。その結果、x << 1はx * 2と同じで、x >> 1はx / 2と同じですが、負の無限大に切り捨てられます。
これらは基本的に算術演算子であり、他の言語でも同じですが、基本的な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)
}
}
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;
}
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);
}
彼らはすべて出力します
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
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
<<
左シフトです。 >>
左のオペランドが符号付き整数の場合は符号拡張右シフトであり、左のオペランドが符号なし整数の場合はゼロ拡張右シフトです。
よりよく理解するため>>
に
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になります)。補体)。