今回のテーマは、「シフト演算」である。
けた移動
10進数では、10のべき乗の重みがついているので、左へ1けた移動すると、10倍になる。
例えば、「123」は「ひゃく2じゅうさん」であるが、左へ1けた移動すると、「せん2ひゃく3じゅう」となる。
2進数では、2のべき乗の重みがついている。左に1けた移動させれば2倍になり、右に1けた移動させれば2分の1になる。けた移動することで、各けたの重みが変わるからである。
けたを移動することをシフトという。左シフトで、かけ算が、右シフトでわり算ができるのである。
左右にシフトして、かけ算、わり算
2進数の各けたをビットと呼ぶ。必ず2進数のかけ算やわり算をするわけでなく、ビット列を左か右に移動するのがシフトである。
論理シフト(全ビット対象)
単に「シフト」とあれば、全ビットが対象となる論理シフトのことを指す。
例えば、ある数を4倍=22倍したい場合には、2ビット左シフトする。
- 全ビットを左にけた移動する。
- シフトによってあふれたけたは捨て、空いたビットには0を入れる。
- 正数に限り、左にkビットシフトすると2k倍になる。
- 全ビットを右にけた移動する。
- シフトによってあふれたけたは捨て、空いたビットには0を入れる。
- 正数に限り、右にkビットシフトすると2k分の1倍になる。
なお、2の補数で負数を表すと、左端のビットは符号ビットとなる。論理シフトでは符号ビットもシフトの対象とするため、負数のかけ算、わり算には使えない。
算術シフト(符号ビット以外が対象)
符号ビットを除いてシフトすることで、負数のかけ算、わり算ができるのが算術シフトである。
なお、この際に注意するのが、オーバーフロー(あふれ)である。例えば8ビットならシフト演算後の結果が、ー128~127の範囲になければ、オーバーフローが発生する。
- 符号ビットを除き、左へけた移動する。
- シフトによってあふれたビットは捨て、空いたビットは0を入れる。
- 負数も含めて、左にkビット移動すると2k倍になる。
- 符号ビットを除き、右へけた移動する。
- シフトによってあふれたビットは捨て、空いたビットには符号と同じものを入れる。
- 負数も含めて、左にkビット移動すると2k分の1倍になる。
10進数のー20は、+20の2進数「00010100」の2の補数をとった「11101100」である。
これを左に2ビット算術シフトすると「10110000」となる。この2の補数を求めて、正数に直すと、「01010000」となり、これは、10進数の80であるから、「10110000」はー80である。負数であっても4倍されている。
一方、ー20を右に2ビット算術シフトした値は、ー5となっている。すなわち、ー20を4で割った数値となる。
いかがであろうか。シフト演算もコンピュータではよく使われる。しっかりと理解しておきたい。
(参考)うかる! 基本情報技術者 [午前編] 福嶋 宏訓 (著) 日本経済新聞出版
コメント