【PL/I学習|実務向け】PL/I BOOL関数徹底解説:16種類のビット論理演算を自在に操る

1. 導入:なぜ今、BOOL組み込み関数を学ぶのか?

メインフレーム環境で長年稼働しているPL/Iアプリケーションには、現代のプログラマには馴染みの薄い、しかし非常に強力な機能が数多く存在します。その一つが、今回ご紹介するBOOL組み込み関数です。

この関数は、二つのビット文字列に対して、任意の論理演算を適用するという、一見シンプルな機能に見えます。しかし、その真価は「任意の論理演算」の指定方法、すなわち真理値表の定数指定に隠されています。AND、OR、XORといった基本的な演算だけでなく、合計16種類全ての論理結合を単一の関数呼び出しで実現できるのです。

なぜこれが重要なのでしょうか?
それは、BOOL関数がメインフレームのハードウェア(ビットプレーン演算)に直結する設計となっており、特定のビット操作において極めて高いパフォーマンスを発揮する可能性があるからです。また、レガシーコードの解析や、他言語への移行プロジェクトにおいては、この難解な真理値表を正確に解読し、現代的な演算子に読み替えるスキルが不可欠となります。

本記事では、このBOOL組み込み関数の「秘奥義」を解き明かし、実務で役立つ知識と具体的なコード例を提供します。

2. 基礎知識:ビット文字列と真理値表の基本

まず、BOOL関数を理解するために必要な基礎知識を確認しましょう。

  • ビット文字列 (BIT STRING)
    PL/Iにおけるビット文字列は、’1’と’0’の並びで構成されるデータ型です。例えば、’10101100’B のように記述され、それぞれがビット単位の情報を持ちます。ファイルフラグやステータス情報の管理など、様々な場面で利用されます。
  • 論理演算
    ビット単位で行われる演算で、代表的なものにAND (&)、OR (|)、XOR (^) などがあります。これらの演算は、入力ビットの組み合わせに応じて出力ビットを決定します。
  • 真理値表 (Truth Table)
    論理演算の全ての結果をまとめた表です。2つの入力(AとB)に対して、考えられる組み合わせは (A=0, B=0)、(A=0, B=1)、(A=1, B=0)、(A=1, B=1) の4通りです。それぞれの入力に対して出力が0か1のどちらかになるため、2の4乗、つまり16種類の論理結合が存在します。BOOL組み込み関数は、この16種類の論理結合全てを、3番目の引数で指定できるという特徴を持ちます。

BOOL関数は、2つのビット文字列を引数にとり、3番目の引数で指定された真理値表に従って、対応するビット位置ごとに論理演算を適用し、結果をビット文字列で返します。

3. 実装/解決策:真理値表の定数指定を読み解く

BOOL関数の構文は以下の通りです。

RES = BOOL(A, B, 真理値表指定);

ここで重要なのが、3番目の引数である「真理値表指定」です。これは4ビットのビット定数で指定され、各ビットが特定の入力組み合わせに対する出力値を示します。

PL/IのBOOL関数における真理値表のビットの並びは、IBMメインフレームのCPU命令(例えばTM、NC、OC、XCなど)の慣習に従い、以下の順序で出力ビットを記述します。

  • 1ビット目 (左端): 入力Aが1、入力Bが1 の場合の出力
  • 2ビット目: 入力Aが1、入力Bが0 の場合の出力
  • 3ビット目: 入力Aが0、入力Bが1 の場合の出力
  • 4ビット目 (右端): 入力Aが0、入力Bが0 の場合の出力

このルールに基づき、いくつかの代表的な論理演算の真理値表定数を見てみましょう。

  • AND演算 (‘1000’B)
    A=1, B=1 の時のみ出力が1になります。その他の場合は0です。
    (A=1,B=1) -> 1
    (A=1,B=0) -> 0
    (A=0,B=1) -> 0
    (A=0,B=0) -> 0
    よって、’1000’B
  • OR演算 (‘1110’B)
    A=0, B=0 の時のみ出力が0になります。その他の場合は1です。
    (A=1,B=1) -> 1
    (A=1,B=0) -> 1
    (A=0,B=1) -> 1
    (A=0,B=0) -> 0
    よって、’1110’B
  • XOR演算 (‘0110’B)
    AとBが異なる場合にのみ出力が1になります。
    (A=1,B=1) -> 0
    (A=1,B=0) -> 1
    (A=0,B=1) -> 1
    (A=0,B=0) -> 0
    よって、’0110’B
  • NOT A 演算 (‘0011’B)
    Aが0の時に出力が1、Aが1の時に出力が0になります(Bの値は結果に影響しません)。
    (A=1,B=1) -> 0
    (A=1,B=0) -> 0
    (A=0,B=1) -> 1
    (A=0,B=0) -> 1
    よって、’0011’B
  • NOT B 演算 (‘0101’B)
    Bが0の時に出力が1、Bが1の時に出力が0になります(Aの値は結果に影響しません)。
    (A=1,B=1) -> 0
    (A=1,B=0) -> 1
    (A=0,B=1) -> 0
    (A=0,B=0) -> 1
    よって、’0101’B

このように、真理値表の定数指定を理解することで、BOOL関数がどのような論理演算を実行しているのかを正確に把握することができます。

4. サンプルプログラム:BOOL関数によるビット操作

以下に、PL/IでBOOL関数を使用し、様々な論理演算を実行するサンプルコードを示します。標準の論理演算子と比較することで、BOOL関数の動作をより明確に理解できます。

DCL A BIT(8) INITIAL('10101100'B); / 最初のビット文字列 /
DCL B BIT(8) INITIAL('11001010'B); / 2番目のビット文字列 /
DCL RES BIT(8); / 結果を格納するビット文字列 /

PUT SKIP LIST('--- BOOL関数による論理演算 ---');
PUT SKIP LIST('A = ' || A);
PUT SKIP LIST('B = ' || B);
PUT SKIP;

/ AND演算 /
RES = BOOL(A, B, '1000'B); / 真理値表: (A=1,B=1)->1, その他->0 /
PUT SKIP LIST('AND (BOOL) = ' || RES);
PUT SKIP LIST('AND (&) = ' || (A & B)); / 標準演算子によるANDと比較 /
PUT SKIP;

/ OR演算 /
RES = BOOL(A, B, '1110'B); / 真理値表: (A=0,B=0)->0, その他->1 /
PUT SKIP LIST('OR (BOOL) = ' || RES);
PUT SKIP LIST('OR (|) = ' || (A | B)); / 標準演算子によるORと比較 /
PUT SKIP;

/ XOR演算 /
RES = BOOL(A, B, '0110'B); / 真理値表: A!=B->1, A=B->0 /
PUT SKIP LIST('XOR (BOOL) = ' || RES);
PUT SKIP LIST('XOR (^) = ' || (A ^ B)); / 標準演算子によるXORと比較 /
PUT SKIP;

/ NOT

コメント

タイトルとURLをコピーしました