ビット演算 | やさしい基礎理論


2024-05-28 更新

この連載は、基本情報技術者試験の受験者を対象としたものです。

多くの受験者が苦手としている「情報の基礎理論」の分野から毎回1つずつテーマをあげて、やさしくポイント解説と問題解説を行います。苦手分野を克服して、試験の得点をアップしましょう。

今回のテーマは、 ビット演算 です。

ビット単位の論理演算

ビット演算は、データを2進数で表して演算するものです。
ビット演算には、「ビット単位の論理演算」と「ビット単位のシフト演算」があります。
ビットは、「2進数の桁」という意味です。ビット単位の論理演算は、2つの2進数のデータで桁ごとに論理演算を行います。
ビット単位のシフト演算は、2進数のデータを指定した桁数だけずらします。

図1に、ビット単位の論理演算の例を示します。
ビット単位の論理演算は、特定の桁だけを覆い隠す(マスクする)ように変化させる演算なので、「マスク演算」とも呼ばれます。
ここでは、マスクされるデータを「データ」、特定の桁を指定するデータを「マスク」で示しています。

【図1】 ビット単位の論理演算の例

(1)AND演算
    01010101 データ
AND 00001111 マスク
―――――――――――――
    00000101 演算結果
マスクで0になっている桁が0になりマスクで1になっている桁は変化しない

(2)OR演算
    01010101 データ
OR  00001111 マスク
―――――――――――――
    01011111 演算結果
マスクで0になっている桁は変化せずマスクで1になっている桁が1になる

(3)XOR演算
    01010101 データ
XOR 00001111 マスク
―――――――――――――
    01011010 演算結果
マスクで0になっている桁は変化せずマスクで1になっている桁が反転する

ビット単位のAND演算の結果は以下の通りです。

0 AND 0 = 0、0 AND 1 = 0、1 AND 0 = 0、1 AND 1 = 1

したがって、マスクで0になっている桁が0になり、マスクで1になっている桁は変化しません。
ここでは、マスクが00001111なので、データの上位4桁がすべて0になり、下位4桁は変化しません。
このように、ビット単位のAND演算は、データの特定の桁だけをすべて0にして、残りの桁を変化させない場合に使われます。

 

ビット単位のOR演算の結果は以下の通りです。

0 OR 0 = 0、0 OR 1 = 1、1 OR 0 = 1、1 OR 1 = 1

したがって、マスクで0になっている桁は変化せず、マスクで1になっている桁が1になります。
ここでは、マスクが00001111なので、データの上位4桁は変化せず、下位4桁がすべて1になります。
このように、ビット単位のOR演算は、データの特定の桁だけをすべて1にして、残りの桁を変化させない場合に使われます。

 

ビット単位のXOR演算の結果は以下の通りです。

0 XOR 0 = 0、0 XOR 1 = 1、1 XOR 0 = 1、1 XOR 1 = 0

したがって、マスクで0になっている桁は変化せず、マスクで1になっている桁が反転(0が1になり、1が0になること)します。
ここでは、マスクが00001111なので、データの上位4桁は変化せず、下位4桁が反転します。
このように、ビット単位のXOR演算は、データの特定の桁だけを反転して、残りの桁を変化させない場合に使われます。

ビット単位のシフト演算

ビット単位のシフト演算は、2進数のデータを指定した桁数だけずらします。

上位桁(左方向)にずらすことを「左シフト」と呼び、下位桁(右方向)にずらすことを「右シフト」と呼びます。
それぞれに「論理シフト」と「算術シフト」があり、「論理左シフト」「論理右シフト」および「算術左シフト」「算術右シフト」と呼びます。

シフトは、レジスタを使って行われます。
レジスタは、コンピュータの演算制御装置であるCPUの内部にあるデータ格納領域です。
CPUの種類によってレジスタのサイズは、決まっています。
たとえば、レジスタのサイズが8ビットなら、左シフトで上位桁からはみ出した数値は失われ、右シフトで下位桁からはみ出した数値は失われます。
左シフトでは下位桁に空きができ、右シフトでは上位桁に空きができますが、ここに何を入れるかが、論理シフトと算術シフトで異なります。

論理シフトでは、左シフトで空いた下位桁には0を入れ、右シフトで空いた上位桁にも0を入れます。

図2に論理シフトの例を示します。
論理シフトは、単に桁をずらすために使われます。ここでは、シフト前とシフト後のデータを示しています。
レジスタのサイズは、8ビットだとします。

【図2】 論理シフトの例

(1)1ビットの論理左シフト
00111100 シフト前
01111000 シフト後
※左シフトで空いた下位桁には0を入れる。

(2)1ビットの論理右シフト
00111100 シフト前
00011110 シフト後
※右シフトで空いた上位桁には0を入れる。

算術シフトは、左シフトで乗算を実現し、右シフトで除算を実現します。
2進数は、左に1桁シフトするごとに値が2倍になり、右に1桁シフトするごとに値が1/2になります。
これらで、2を掛ける乗算と2で割る除算を実現するのです。
その際に、2の補数表現(この連載の第2回で説明しています)を使ったマイナスの値でも、正しい乗算と除算の結果が得られるように、最上位桁の符号ビットをシフトの対象とせずに、左シフトで空いた下位桁には0を入れますが(これは論理シフトと同じです)、右シフトで空いた上位桁には符号ビットと同じ値(プラスの値なら0、マイナスの値なら1)を入れます。

こうすると、マイナスの値でも、正しい乗算と除算の結果が得られるのです。

図3に算術シフトの例を示します。
ここでも、シフト前とシフト後のデータを示しています。レジスタのサイズは、8ビットだとします。

【図3】 算術シフトの例

(1)1ビットの算術左シフト(2を掛ける乗算)
11111100 シフト前(10進数でマイナス4)
11111000 シフト後(10進数でマイナス8)
符号ビットをシフトの対象とせず、左シフトで空いた下位桁には0を入れる。

(2)1ビットの算術右シフト(2で割る除算)
11111100 シフト前(10進数でマイナス4)
11111110 シフト後(10進数でマイナス2)
符号ビットをシフトの対象とせず、右シフトで空いた上位桁には符号ビットと同じ値(ここでは1)を入れる。

ビット演算に関する問題の例(その1)

ビット演算に関する問題を2つ紹介しましょう。
はじめは、ビット単位の論理演算の問題です。

問1(出典:H28秋問1)

8ビットのビット列の下位4ビットが変化しない操作はどれか。

ア 16進表記 0F のビット列との排他的論理和をとる。
イ 16進表記 0F のビット列との否定論理積をとる。
ウ 16進表記 0F のビット列との論理積をとる。
エ 16進表記 0F のビット列との論理和をとる。

問題では、0Fという16進数が使われています。
ビット演算は、データを2進数で表して演算するものなので、16進数の0Fを2進数に変換しましょう。

16進数は、16で桁上がりするので、1桁を0、1、2、3、4、5、6、7、8、9、A、B、C、D、E、Fで表します。
A~Fは、10進数なら10~15です。16進数の1桁は、2進数の4桁になります。
2進数の4桁の重みは、上位桁から順に8、4、2、1なので、これらをどのように足し合わせれば16進数の1桁になるかを考えて変換します。

0は、8、4、2、1のどれも足さないので、すべての桁が0の0000です。
Fは10進数で15であり、15=8+4+2+1なので、すべての桁が1の1111です。

したがって、16進数の0Fは、2進数で00001111です。

この00001111をマスクとして、選択肢に示されたどの演算を行うと、下位4ビットが変化しないかを答えます。
選択にある排他的論理和、否定論理積、論理積、論理和は、XOR、NAND(NOT ANDという意味で、AND演算の結果をNOT演算します)、AND、ORの日本語名です。

00001111は、下位4ビットがすべて1です。
XOR演算では、1に対応する桁が反転します。
NAND演算では、AND演算で1に対応する桁が変化し、さらにNOT演算(すべての桁を反転する演算)するので、下位4ビットを含むすべての桁が反転します。
AND演算では、1に対応する桁が変化しません。
OR演算では、1に対応する桁がすべて1になります。

したがって、下位4ビットが変化しないのは、AND演算(論理積)であり、選択肢ウが正解です。

ビット演算に関する問題の例(その2)

次は、ビット単位のシフト演算の問題です。

問2(出典:H25秋問2)

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

ア 2AF3   イ 6AF3   ウ AF34   エ EAF3

ここでもABCDという16進数が使われているので、2進数に変換してから、シフト演算しましょう。

A、B、C、Dは、10進数で10、11、12、13です。
10=8+0+2+0なので、1010です。
11=8+0+2+1なので、1011です。
12=8+4+0+0なので、1100です。
13は、8+4+0+1なので、1101です。

したがって、16進数のABCDは、2進数で1010101111001101です。

ここでは、32ビットのレジスタなので、32桁の2進数を保持でき、左シフトで上位桁からはみ出した数値と、右シフトで下位桁からはみ出した数値は消えてなくなります。
1010101111001101という32ビットのデータを2ビットシフトすると、下位2桁の01がはみ出し、空いた上位2桁に00が入って、0010101011110011になります。

選択肢が16進数になっているので、0010101011110011を16進数にしましょう。

2進数を下位桁から4ビットずつに区切って、0010、1010、1111、0011として、それぞれを16進数に変換します。

0010は、0+0+2+0=2です。
1010は、8+0+2+0=10なので16進数でAです。
1111は、1+1+1+1=15なので16進数でFです。
0011は、0+0+1+1=3です。

したがって、0010101011110011は、16進数で2AF3であり、選択肢アが正解です。

基本情報技術者試験の公開問題を見ると、過去に出題された問題の再利用が多いことがわかります。
したがって、試験に合格するために最も効率的で効果的な学習方法は、過去問題を数多く解き、できなかった問題があれば、できるようになるまで練習することです。
もしも、今回取り上げた問題がすぐにできなかったら、できるようになるまで練習してください。

それでは、またお会いしましょう!

label 関連タグ
科目A試験は、
免除できます。
独習ゼミで科目A試験を1年間免除して、科目B試験だけに集中しましょう。
免除試験を受けた 74.9% の方が、
科目A免除資格を得ています。
科目A免除試験 最大 2 回の
受験チャンス !
info_outline
科目A免除試験 最大 2 回の
受験チャンス !
詳しく見てみるplay_circle_filled
label これまでの『やさしい基礎理論』の連載一覧 label 著者