ビットシフト備忘録
ビットシフト
>>
右へ
<<
左へ
ある数を 2 倍, 1/2 倍(小数切捨)するときに有用。
この仕組みを理解するため、例、右シフト 1 がどうして 1/2 倍になるかを考える。
21 を 2 進数表記すると 10101 である。
parseInt(10101,2) = 21
2 進数では、各位の値が 1 (有る) か 0 (無い) かで表される。
16 8 4 2 1
1 0 1 0 1
全ての位の和が、 21 である。
(16 * 1) + (8 * 0) + (4 * 1) + (2 * 0) + (1 * 1) = 21
これを右シフト 1 する。
21 >> 1
16 8 4 2 1
1 0 1 0 1
(16 * 0) + (8 * 1) + (4 * 0) + (2 * 1) + (1 * 0) = 10
21 / 2 = 10.5 だが、ビット演算では小数が切り捨てられる。
x>>1 = Math.floor(x/2)
2 進数では、位が上がるごとに、値は 1,2,4,8,16,32,64,128... と大きくなっていく。
概ね…
どの位の値も、直前の位の値の 2 倍になっている。
どの位の値も、直後の位の値の 1/2 倍になっている。
右シフト 1 することは、各位の値を 1/2 倍することと等しい。
16 8 4 2 1
1 0 1 0 1
↓
8 4 2 1 0
1 0 1 0 1
16→8, 8→4, 4→2, 2→1, 1→0
各位の値をすべて 1/2 倍して、足しているから、全体を 1/2 倍していることになる。
a/2 + b/2 + c/2 = (a+b+c)/2
(16 * 1) + (8 * 0) + (4 * 1) + (2 * 0) + (1 * 1) = 21
( 8 * 1) + (4 * 0) + (2 * 1) + (1 * 0) + (0 * 1) = 10
1 を 1/2 倍すると 0.5 である。 ビット演算では、これを 0 とする。
もしも、ビット演算に、 0.5 の位があるとしたら…
16 8 4 2 1
1 0 1 0 1
↓
8 4 2 1 0.5
1 0 1 0 1
正確な値を求めることができる。