49  ゲート

これまではコンピューターにおいて重要な記数法である2進数について学んだ.そして,0と1のビットを使って,数値や文字などのデータを表現する方法についても触れた.

ここでは,2進数の計算を行うための装置であるゲートについて学ぶ.

学習の目標は次の通りである:

49.1 ブール演算

ビットは一般的に0または1と表現されるが,FalseまたはTrueという真理値としての表現もよく使われる.

このような真理値(0と1)を扱うための数学的な体系をブール代数(Boolean algebra)と呼ぶ.ブール代数は,イギリスの数学者ジョージ・ブール(George Boole)によって考案された.ブール演算は,AND,OR,NOT,XORなどの論理演算子を使って真偽値を操作する.

49.2 ゲート

コンピューターでは,ゲート(gate,論理ゲート,logic gate)と呼ばれる装置を使ってブール演算を実行する.ゲートは,1つまたは複数の入力信号を受け取り,それらの信号を処理して出力信号を生成する.

ここでは,以下の基本的な論理ゲートを紹介する.

  • OR
  • AND
  • NOT
  • XOR
  • NAND
  • NOR

これらのゲートの紹介には,論理式,真理値表,記号を使う.

  • 論理式(Boolean expressions)は,数学記号を使って,数式で真理値の演算を表現する.
  • 真理値表(truth table)は,ゲートのすべての入力組み合わせに対して,出力の真理値を示す表である.
  • 記号(MIL symbols)は,論理ゲートを図で表現するための記号である.CircuitVerseという論理回路のシミュレータを使って,ゲートの動作を視覚的に確認することもできる.

49.2.1 ORゲート

AB を真理値とするとき,AB の論理和(logical disjunction)は,A \lor B と書く.

AB の少なくとも一方が1のとき,A \lor B = 1 となる.

論理和の真理値表は以下の通りである.

A B A \lor B
0 0 0
0 1 1
1 0 1
1 1 1

論理和の演算を行うORゲートは次の記号で表現される.

ORゲート

49.2.2 ANDゲート

AB を真理値とするとき,AB論理積(logical conjunction)は,A \land B と書く.

AB の両方が1のとき,A \land B = 1 となる.

論理積の真理値表は以下の通りである.

A B A \land B
0 0 0
0 1 0
1 0 0
1 1 1

論理積の演算を行うANDゲートは次の記号で表現される.

ANDゲート

49.2.3 NOTゲート

A を真理値とするとき,A否定(logical negation)は,\lnot A と書く.

A1のとき,\lnot A = 0となり,A0のとき,\lnot A = 1となる.

否定の真理値表は以下の通りである.

A \lnot A
0 1
1 0

否定の演算を行うNOTゲートは次の記号で表現される.

NOTゲート

49.2.4 XORゲート

ABを真理値とするとき,AB排他的論理和(exclusive or)は,A \oplus Bと書く.

ABのうち一方だけが1のとき,A \oplus B = 1となる.

排他的論理和の真理値表は以下の通りである.

A B A \oplus B
0 0 0
0 1 1
1 0 1
1 1 0

排他的論理和の演算を行うXORゲートは次の記号で表現される.

XORゲート

49.2.5 NANDゲート

ABを真理値とするとき,AB否定論理積は,A \uparrow Bと書く.NANDはNot ANDの略で,ANDゲートの出力を否定したものである.

A \uparrow B = \lnot (A \land B)

否定論理積の真理値表は以下の通りである.

A B A \uparrow B
0 0 1
0 1 1
1 0 1
1 1 0

否定論理積の演算を行うNANDゲートは次の記号で表現される.

NANDゲート

49.2.6 NORゲート

ABを真理値とするとき,AB否定論理和は,A \downarrow Bと書く.NORはNot ORの略で,ORゲートの出力を否定したものである.

A \downarrow B = \lnot (A \lor B)

否定論理和の真理値表は以下の通りである.

A B A \downarrow B
0 0 1
0 1 0
1 0 0
1 1 0

否定論理和の演算を行うNORゲートは次の記号で表現される.

NORゲート

49.3 まとめ

  • ANDゲートは,両方の入力が1のときに出力が1になる.
  • ORゲートは,少なくとも一方の入力が1のときに出力が1になる.
  • NOTゲートは,入力が1のときに出力が0になり,入力が0のときに出力が1になる.
  • XORゲートは,入力のうち一方だけが1のときに出力が1になる.
  • NANDゲートは,ANDゲートの出力を否定したもので,両方の入力が1のときに出力が0になる.
  • NORゲートは,ORゲートの出力を否定したもので,両方の入力が0のときに出力が1になる.
ゲート 論理式
AND A \land B
OR A \lor B
NOT \lnot A
XOR A \oplus B
NAND A \uparrow B
NOR A \downarrow B

49.4 プログラミング言語での論理演算

C言語では,真理値は整数型で表現され,0は偽(False),1は真(True)として扱われる.

以下のC言語のコードは,2 > 1が真であり,1を出力する.2 < 1が偽であり,0を出力する.

#include <stdio.h>

int main() {
  printf("%d\n", 2 > 1); // 1
  printf("%d\n", 2 < 1); // 0
  return 0;
}

Pythonでは,TrueFalseを使って真理値を表現する.

以下のPythonのコードは,2 > 1が真であり,Trueを出力する.2 < 1が偽であり,Falseを出力する.

print(2 > 1)  # True
print(2 < 1)  # False

C言語では,論理和の演算は||演算子を使って表現される.例えば,A || Bは,AまたはBのいずれかが真である場合に真を返す.

#include <stdio.h>
int main() {
    int A = 1; // 真
    int B = 0; // 偽
    printf("A OR B = %d\n", A || B); // 出力: 1
    return 0;
}

C言語では,論理積の演算は&&演算子を使って表現される.例えば,A && Bは,ABの両方が真である場合に真を返す.

#include <stdio.h>
int main() {
    int A = 1; // 真
    int B = 0; // 偽
    printf("A AND B = %d\n", A && B); // 出力: 0
    return 0;
}

C言語では,否定の演算は!演算子を使って表現される.例えば,!Aは,Aが真である場合に偽を返し,Aが偽である場合に真を返す.

#include <stdio.h>
int main() {
    int A = 1; // 真
    printf("NOT A = %d\n", !A); // 出力: 0
    return 0;
}

49.4.1 練習問題

ユーザーから2つの真理値(0または1)を入力として受け取り,AND,OR,NOT,XORの演算結果を表示するC言語のプログラムを作成せよ.

作成したプログラムを実行すると,次のような出力が得られる.Enter AEnter Bの後に,0または1を入力することができる.

Please enter A and B, where A and B are either 0 or 1.
Enter A: __1__
Enter B: __0__
A = 1, B = 0

*** Logical Operations ***
A AND B = 0
A OR B = 1
NOT A = 0
A XOR B = 1

49.4.1.1 解答例

#include <stdio.h>

int main() {
    int A, B;
    printf("Please enter A and B, where A and B are either 0 or 1.\n");
    printf("Enter A: ");
    scanf("%d", &A);
    printf("Enter B: ");
    scanf("%d", &B);
    printf("A = %d, B = %d\n", A, B);

    printf("*** Logical Operations ***\n");
    printf("A AND B = %d\n", A && B);
    printf("A OR B = %d\n", A || B);
    printf("NOT A = %d\n", !A);
    printf("A XOR B = %d\n", A ^ B);
    return 0;
}