Edited at

Goでは、nビットシフトは1ビットシフトをn回行ったのと同じ(CやJavaは違う)

More than 5 years have passed since last update.

Goの言語仕様のシフト演算子のところを読んでみると、nビットシフトするのは1ビットのシフトをn回繰り返したのと同じ結果になると書いてある。

これはCやJavaの言語仕様とは違う。

Goのビットシフトの仕様では、無限に左側に符号拡張されたビット列をシフトしたのと同じ結果になる。たとえばx >> n(xは符号あり整数、nは符号なし整数)という式の結果は、nがxの幅より大きいとき、0か-1になる。xが0以上なら最上位の符号ビットが0なので全部のビットが右の方に消えて結果は0。xが0未満なら符号ビットが1なので、符号付きシフトで左から1がでてきて結果はすべて1のビット列、すなわち-1になる。

Cでは左辺値の型のサイズより大きい値でシフトしたときの結果は定義されていない。CだとCPUのシフト命令1命令にコンパイルされるのが自然だけど、レジスタサイズより大きいシフトはCPUによって違ったりするだろうから、これはまあそうだろうなという感じだ。

Javaでは左辺値の型がnビット幅なら、右辺値の下位nビットだけがシフト量として解釈されるということになっている。JavaではJavaらしくどのCPUでも同じ結果になるが、暗黙のうちに右辺値がマスクされるのと同じなのでちょっとわかりにくい。

Goの仕様はわかりやすい(少なくとも一番驚きの少ない結果になる)といってよいと思う。