資格道場 › レッスン一覧 › 基礎理論
基礎理論・3/13・12分

シフト演算で掛け算・割り算をする

ゴール

左シフトを組み合わせて x を3倍・5倍・10倍にする手順と、論理右シフト・算術右シフト(負数を含む)を手で計算できるようになる。上位と下位のビットを入れ替えた値を、÷ と % を使った式で表せるようになる。

2進数ではビットを1桁ずらすだけで2倍や1/2になるので、CPU は掛け算・割り算をシフトと足し算に置き換えて速く計算します。科目Aでは「x を何倍にする操作はどれか」「算術右シフトした結果はいくつか」という形で、繰り返し出題されています。

このレッスンで稽古する(用語チェック・過去問)

結論:左に1ビットずらすと2倍、右に1ビットずらすと1/2

シフト演算とは、ビット列(0と1の並び)を丸ごと左か右へずらす操作です。左に n ビットずらすと 2^n 倍、右に n ビットずらすと 2^n で割った値(割り切れない分は切り捨て)になります。

たとえば 10進数の 37 の右に 0 を付けて 370 にすると10倍になります。2進数で同じことをすると、1桁あたり2倍になります。

操作 値の変化 例(x=3 = 0011)
1ビット左シフト 2倍 0110 = 6
2ビット左シフト 4倍 1100 = 12
3ビット左シフト 8倍 11000 = 24
1ビット右シフト 1/2(切り捨て) 0001 = 1

左へずらしてレジスタ(CPU 内の小さな記憶場所)の幅からはみ出すことを**桁あふれ(オーバフロー)**といいます。過去問の多くは「桁あふれは起こらないものとする」と断っているので、計算では気にしなくて大丈夫です。

0011= 31ビット左シフト0110= 6(2倍)1ビット左シフト1100= 12(4倍)色付きの箱=右端に新しく入った 0
x=3(0011)を1ビットずつ左へずらすと、1のビットが上位へ移り右端に0が入って、3→6→12と2倍ずつ増える。

最頻出:シフトと足し算で ○倍 を作る

シフトだけで作れるのは 2倍・4倍・8倍…だけです。3倍・5倍・10倍は、シフトした値に元の x を足して作ります。この知識は本試験系と免除試験を合わせて16回出ていて、このレッスンで一番大事です。

解き方は、選択肢の操作を順に x の式へ書き直すだけです。「2ビット左シフト」は 4x、「x を加算」は +x、「さらに1ビット左シフト」は ×2 と置き換えます。

作りたい倍数 分解 操作
3倍 2x + x 1ビット左シフト + x
5倍 4x + x 2ビット左シフト + x
9倍 8x + x 3ビット左シフト + x
10倍 (4x + x) × 2 2ビット左シフト + x、さらに1ビット左シフト
12倍 8x + 4x 3ビット左シフト + 2ビット左シフト

ビット列で書かれた問題では、**末尾に 0 を1個付けると1ビット左シフト(2倍)**と同じ意味になります。b₁b₂…bₙ0 は 2倍、b₁b₂…bₙ00 は 4倍です。

x(例 3)2ビット左シフト(×4)4x(12)元の x を加算(+x)5x(15)1ビット左シフト(×2)10x(30)(4x + x) × 2
10倍は「2ビット左シフト→x を加算→1ビット左シフト」の順で 4x→5x→10x と作る(例 x=3)。

右シフトには「論理」と「算術」の2種類がある

右へずらすと左端(上位)に空きができます。空いた所を何で埋めるかで2種類に分かれ、この違いが試験でよく問われます。

論理シフト 算術シフト
扱う数 符号を考えないビット列(符号なし) 2の補数で表した符号付きの数
右シフトで空いた上位を埋める値 常に 0 符号ビットと同じ値(負なら1、正なら0)
符号ビット ほかのビットと同じようにずれる 残る(正負が変わらない)
負数を右シフトした結果 大きな正の数になって意味が崩れる 1/2^n 倍の負数になる

たとえるなら、算術シフトは「先頭の旗(符号)を立てたまま列全体を後ろへ詰める」操作です。論理シフトは旗のことを考えず、空いた所に 0 を入れます。

論理右シフトは16進を2進に開いてから

16進数1桁は2進数4桁にそのまま対応します。16進 → 2進に展開 → ずらす → 4桁ずつ区切って16進に戻す、の順で計算します。

16進の桁をそのまま横にずらして「AF34」のようにするのは誤りです。1ビットずらすだけで、4桁区切りの中身がすべて変わります。

算術右シフトで負数を割る

前のレッスンの2の補数(ビットを反転して1を足し、負数を表す方法)が、ここで役に立ちます。負数を算術右シフトすると、空いた上位に 1 が入るので、負のまま 1/2^n になります。

注意点は端数の扱いです。算術右シフトの端数は小さい方へ切り捨てられます。−20 ÷ 8 = −2.5 は −2 ではなく −3 になります。

−20 = 11101100(8ビット)11101100論理右シフト 3ビット:上位に 000011101= 29(正の数になり意味が崩れる)算術右シフト 3ビット:上位に符号の 111111101= −3(−2.5 を小さい方へ切り捨て)右端からはみ出した 100 は捨てる
8ビットの −20(11101100)を3ビット右へずらすと、論理シフトは上位に0が入り29に、算術シフトは1が入り−3になる。

上位と下位を入れ替える式(免除試験で出題)

16ビットの x では、上位8ビットは x÷256(商)、下位8ビットは x%256(余り)です。2^8 = 256 だからです。入れ替えると、下位にあった値が上位(×256)へ、上位にあった値が下位へ移るので、(x%256)×256 + (x÷256) になります。

2桁の2進数 x₁x₂ でも考え方は同じです。x = 2x₁ + x₂、x₁ = int(x/2) なので、入れ替えた値は 2x₂ + x₁ = 2x − 3·int(x/2) になります。迷ったら x = 1 や x = 2 を代入して確かめるのが確実です。

x(16ビット)上位8ビットx÷256(商)下位8ビットx%256(余り)x%256×256 して上位へx÷256そのまま下位へ(x%256)×256 + (x÷256)
16ビットの x を上位8ビット(x÷256)と下位8ビット(x%256)に分け、入れ替えると (x%256)×256 + (x÷256) になる。
例題 1

x を10倍にするシフト操作を選ぶ

数値を 2 進数で表すレジスタがある。このレジスタに格納されている正の整数 x を 10 倍にする操作はどれか。ここで,桁あふれは起こらないものとする。

ア x を 2 ビット左にシフトした値に x を加算し,更に 1 ビット左にシフトする。
イ x を 2 ビット左にシフトした値に x を加算し,更に 2 ビット左にシフトする。
ウ x を 3 ビット左にシフトした値と,x を 2 ビット左にシフトした値を加算する。
エ x を 3 ビット左にシフトした値に x を加算し,更に 1 ビット左にシフトする。

出典:平成29年度 秋期 基本情報技術者試験 午前 問1

解き方と答えを見る
  1. 10x を「シフト(2のべき乗倍)と足し算」に分解する。10x = (4x + x) × 2
  2. 4x は2ビット左シフト、+x は加算、×2 は1ビット左シフトにあたる
  3. 選択肢を式に直して確かめる。ア:(4x + x) × 2 = 5x × 2 = 10x
  4. イ:(4x + x) × 4 = 20x。ウ:8x + 4x = 12x。エ:(8x + x) × 2 = 18x
  5. 10x になるのはアだけ

答え:ア(2ビット左シフトして x を加え、さらに1ビット左シフトする)

例題 2

2ビット左シフトして x を加えると何倍になるか

数値を 2 進数で格納するレジスタがある。このレジスタに正の整数 x を設定した後,“レジスタの値を 2 ビット左にシフトして,x を加える”操作を行うと,レジスタの値は x の何倍になるか。ここで,あふれ(オーバフロー)は,発生しないものとする。

ア 3
イ 4
ウ 5
エ 6

出典:平成28年度 春期 基本情報技術者試験 午前 問1

解き方と答えを見る
  1. 2ビット左シフト = 2² 倍 = 4x
  2. x を加える:4x + x = 5x

答え:ウ(5倍)

例題 3

16進 ABCD を2ビット論理右シフトする

32 ビットのレジスタに 16 進数 ABCD が入っているとき,2 ビットだけ右に論理シフトした値はどれか。

ア 2AF3
イ 6AF3
ウ AF34
エ EAF3

出典:平成25年度 秋期 基本情報技術者試験 午前 問2

解き方と答えを見る
  1. 16進を2進に展開する:A=1010, B=1011, C=1100, D=1101 → 1010 1011 1100 1101
  2. 右に2ビットずらす。右端の2ビット「01」は消える
  3. 論理シフトなので、空いた上位2ビットを 0 で埋める → 0010 1010 1111 0011
  4. 4桁ずつ16進に戻す:0010=2, 1010=A, 1111=F, 0011=3 → 2AF3
  5. 32ビットのレジスタでも、ABCD より上位はすべて 0 なので結果は変わらない

答え:ア(2AF3)

例題 4

11010000 を2ビット算術右シフトし、00010100 から引く

8 ビットの 2 進数 11010000 を右に 2 ビット算術シフトしたものを,00010100 から減じた値はどれか。ここで,負の数は 2 の補数表現によるものとする。

ア 00001000
イ 00011111
ウ 00100000
エ 11100000

出典:平成24年度 秋期 基本情報技術者試験 午前 問1

解き方と答えを見る
  1. 11010000 は最上位が1なので負の数。10進に直すと 208 − 256 = −48
  2. 2ビット算術右シフト:空いた上位2ビットを符号ビットの1で埋める → 11110100
  3. 11110100 = 244 − 256 = −12(−48 ÷ 4 = −12 と一致)
  4. 00010100 = 16 + 4 = 20
  5. 20 − (−12) = 32
  6. 32 を8ビットの2進にすると 00100000

答え:ウ(00100000)

例題 5

−20 を3ビット算術右シフトする

10 進数の −20 を 2 の補数表現で 8 ビットのレジスタに記憶する。これを右に 3 ビット算術シフトした結果を 10 進数で表したものはどれか。

ア −115
イ −3
ウ −2
エ 27

出典:基本情報技術者試験 科目A免除 修了試験 20110724 実施分 問2

解き方と答えを見る
  1. 20 を8ビットにする:00010100
  2. 2の補数を作る:ビットを反転して 11101011、1を足して 11101100(= −20)
  3. 3ビット算術右シフト:右端の3ビット「100」が消え、上位3ビットを符号ビットの1で埋める → 11111101
  4. 11111101 = 253 − 256 = −3
  5. 確認:−20 ÷ 8 = −2.5 を小さい方へ切り捨てると −3

答え:イ(−3)

例題 6

16ビットの上位8ビットと下位8ビットを入れ替える式

0 以上 65,536 未満の整数 x を,16 ビットの 2 進数で表現して,上位 8 ビットと下位 8 ビットを入れ替える。得られたビット列を 2 進数とみなしたとき,その値を x を用いた式で表したものはどれか。ここで,a÷b は a を b で割った商の整数部分を,a%b は a を b で割った余りを表す。また,式の中の数値は 10 進数である。

ア (x÷256)+(x%256)
イ (x÷256)+(x%256)×256
ウ (x÷256)×256+(x%256)
エ (x÷256)×256+(x%256)×256

出典:基本情報技術者試験 科目A免除 修了試験 20220123 実施分 問1

解き方と答えを見る
  1. 上位8ビットの値 = x ÷ 256、下位8ビットの値 = x % 256
  2. 入れ替え後は、元の下位が上位に来るので (x % 256) × 256
  3. 元の上位は下位に来るので、そのまま x ÷ 256
  4. 合計:(x ÷ 256) + (x % 256) × 256
  5. ウ (x÷256)×256 + (x%256) は元の x そのもので、入れ替わっていない

答え:イ

要点(試験直前に読む)

  • 左に n ビットずらすと 2^n 倍、右に n ビットずらすと 1/2^n(端数は切り捨て)
  • 3倍 = 2x + x、5倍 = 4x + x、10倍 = (4x + x) × 2。選択肢は x の式に直して確かめる
  • 末尾に0を付けると2倍。b…b0 + b…b は3倍
  • 右シフトで空いた上位は、論理シフトなら0、算術シフトなら符号ビットで埋める
  • 負数の算術右シフトは小さい方へ切り捨てる。−20 を3ビットずらすと −3(−2 ではない)
  • 16ビットの上位8ビット = x÷256、下位8ビット = x%256。入れ替えると (x%256)×256 + x÷256

ひっかけ

  • シフト量を少し変えて 12倍・18倍・20倍 になる選択肢を並べる → 選択肢を1つずつ 4x・8x などの式に直して計算する
  • 「2ビット左シフトして x を加える」で、加算前の4倍を選ばせる → 最後の加算まで式に入れる(答えは5倍)
  • 算術シフトの問題で、上位を0で埋めた答え(大きな正の数)や、符号ビットだけ残して空きを0で埋めた答え(−115 など)を混ぜる → 負数の算術右シフトなら、上位はすべて1で埋まる
  • 16進の桁をずらしただけの答え(ABCD → AF34 など)を混ぜる → 必ず2進に展開してからずらす
  • 上下入れ替えの式で、元の値に戻る式や重みの付け方が逆の式を混ぜる → x = 1 などを代入して入れ替わっているか確かめる

用語(12)

シフト演算 しふとえんざん
ビット列全体を左または右へ指定した桁数だけずらす操作。
⚠ ローテート(循環シフト)は、はみ出したビットを反対側へ戻す。シフトでは、はみ出したビットは捨てる。
左シフト ひだりしふと
ビット列を上位方向へずらし、空いた下位を0で埋める操作で、nビットなら値は2^n倍になる。
⚠ 右シフトは1/2^n。「左=増える、右=減る」と覚える。
右シフト みぎしふと
ビット列を下位方向へずらす操作で、nビットなら値は2^nで割った値(端数切り捨て)になる。
⚠ 空いた上位を0で埋めるか符号ビットで埋めるかで、論理と算術に分かれる。
論理シフト ろんりしふと
符号を考えずにずらし、空いたビットを常に0で埋めるシフト。
⚠ 算術シフトとの違いは、右シフトで上位を0で埋めるか符号ビットで埋めるか。負数の問題なら算術シフトを疑う。
算術シフト さんじゅつしふと
2の補数の符号付き数を、符号を保ったままずらすシフトで、右シフトでは空いた上位を符号ビットと同じ値で埋める。
⚠ 論理シフト(常に0で埋める)。問題文の「算術」「論理」の2文字を必ず確認する。
符号ビット ふごうびっと
2の補数表現の最上位ビットで、0なら正(または0)、1なら負を表す。
⚠ 論理シフトでは、ほかのビットと同じようにずれて上書きされる。
2の補数 にのほすう
ビットを反転して1を足すことで負数を表す方法で、8ビットなら −128〜127 を表せる。
⚠ 1の補数は反転するだけで1を足さない。
桁あふれ(オーバフロー) けたあふれ(overflow)
計算結果がレジスタのビット数に収まらず、正しい値を保てなくなること。
⚠ 右シフトで下位から消えるビットは端数の切り捨てで、オーバフローとは呼ばない。
レジスタ れじすた(register)
CPU の中で計算中の値を一時的に置く、高速で小さな記憶場所。
⚠ 主記憶(メモリ)より容量は小さいが、ずっと速い。
上位ビット・下位ビット じょういびっと・かいびっと
ビット列の左側(重みが大きい側)を上位、右側(重みが小さい側)を下位という。
商と余り(÷ と %) しょうとあまり
x を 2^n で割った商は上位側のビットを、余りは下位 n ビットを表す。
⚠ 16ビットを8ビットずつに分けるときは 256 で割る(2^16 = 65536 と混同しない)。
16進数 じゅうろくしんすう
0〜9とA〜F(10〜15)で表す数で、1桁が2進4桁にちょうど対応する。
⚠ 16進の桁をそのままずらしても、ビットシフトにはならない。

このレッスンの過去問

このレッスンで稽古する