【入門編】FIXED BINARYの内部表現とストレージ占有量 – PL/Iの基本構文とデータ制御実践ガイド

こんにちは!メインフレームの世界へようこそ。
JavaやCOBOLといったモダンな、あるいは広く普及している言語の経験がある方にとって、IBMメインフレームの「PL/I(ピーエルアイ)」は、ちょっと古風で近寄りがたい城塞のように見えるかもしれませんね。

特に、データ定義のあたりを覗いてみると、見慣れない記号や数字が並んでいて「うわ、難しそう……」と冷や汗をかいてしまうことも多いはずです。でも、安心してください。一つひとつのルールを紐解いていけば、PL/Iほどロジカルで、ハードウェアの性能を極限まで引き出せる美しい言語はありません。

今回は、そんなPL/Iの基本データ型の中でも、バッチ処理や計算処理で避けて通れない「固定小数点数(FIXED BINARY)」の内部表現とストレージ(メモリ)の占有量について、どこよりも優しく、かつ実務で役立つ深いところまで解説していきますね。

—

1. FIXED BINARYって何だろう?(他言語との比較)

Javaでいうところの `short` や `int`、COBOLでいうところの `USAGE COMP`(計算機用二進表現)に近いものが、PL/Iの `FIXED BINARY`(略して `FIXED BIN`)です。

実数の世界を、コンピュータが一番得意とする「2進数(0と1)」のガチガチの固まりとして正確に扱いたいときに使います。金額の計算や、ループのカウンター、フラグの管理など、基幹システムのあらゆる場所で主役級として活躍しています。

まずは、一番シンプルな宣言を見てみましょう。

DCL WK_COUNT FIXED BIN(15); / 作業用のカウンター /
DCL WK_AMOUNT FIXED BIN(31); / 金額を保持する変数 /

ここで登場する `(15)` や `(31)` という数字、これが今回の主役である「精度(Precision: p)」です。この数字の意味と、コンパイラが裏側でどう動いているのかを覗いてみましょう。

—

2. 精度 `p` とストレージ占有量の不思議な関係

JavaやC言語であれば、「16ビットならこれ」「32ビットならこれ」と型サイズが直感的に決まっていますよね。しかし、PL/Iは少し違います。プログラマが括弧の中に指定する「精度 `p`(有効桁数ではなく、符号を除いた2進数のビット数)」によって、コンパイラが自動的に最適なストレージサイズを割り当ててくれるのです。

ここに、メインフレームならではの「メモリを1バイトたりとも無駄にしない、しかしハードウェアの境界線(アライメント)には従う」という職人芸的な仕組みが隠されています。

ハーフワード(半語)か、フルワード(全語)か?

コンパイラは、あなたが指定した精度 `p` を見て、次のようにストレージを割り当てます。

  • 精度 `p` が 1 ~ 15 の場合
  • ハーフワード(2バイト / 16ビット)の領域が割り当てられます。
  • 精度 `p` が 16 ~ 31 の場合
  • フルワード(4バイト / 32ビット)の領域が割り当てられます。

「あれ? 15桁なら15ビットなのに、なんで2バイト(16ビット)になるの?」と思いましたか?
鋭いですね! 実は、2進数の世界では一番左側の1ビットが「符号(プラスかマイナスか)」のために使われるというお約束があります。

つまり、こういうことです:

  • `FIXED BIN(15)` と宣言すると、「符号1ビット + データ15ビット = 合計16ビット(2バイト)」となり、CPUが一番効率よく処理できる「ハーフワード境界」にピタリと収まるわけです。
  • 同様に、`FIXED BIN(31)` と宣言すると、「符号1ビット + データ31ビット = 合計32ビット(4バイト)」となり、「フルワード境界」に収まります。

—

3. 実務で遭遇する「おやっ?」という落とし穴

レガシーシステムの移行や改修をしていると、前任者が書いたこんなコードに出会うことがあります。

DCL FLAG_ON FIXED BIN(1); フラグなのに FIXED BIN(1) ? /

「たった1フラグ(ON/OFF)なんだから、1ビットあれば十分でしょ!」と思って `FIXED BIN(1)` と書きたくなる気持ち、すごくよく分かります。

しかし、ここでPL/Iの仕様とメインフレームのハードウェアの現実を思い出してください。
コンパイラは `p = 1` を見て、「おっ、1〜15の範囲だな!じゃあ2バイト(16ビット)のハーフワードを割り当てておこう!」と処理します。

つまり、たった「0か1」しか入れない変数であっても、メモリ上ではしっかり2バイトを占有しているのです。「1ビットなんだから1バイトで足りるはず」と思い込んでレイアウト設計をすると、思わぬメモリ消費や構造体(STRUCTURE)のズレを生む原因になるので注意してくださいね。

—

4. 実践!ストレージサイズを確認するPL/Iコード

百聞は一見にしかず。実際にコンパイラがどれくらいのサイズを割り当てているのか、PL/Iのビルトイン関数(組み込み関数)である `STG`(ストレージ関数)を使って確認してみましょう。

以下のサンプルコードは、大文字ベースで記述された実務標準のスタイルです。

/ ————————————————– /
/ FIXED BINARY のストレージサイズ確認用サンプルプログラム /
/ ————————————————– /
TEST_STG: PROC OPTIONS(MAIN);

/ 各種精度の変数を宣言 /
DCL VAR_P5 FIXED BIN(5); / 精度 5 (1〜15の範囲) /
DCL VAR_P15 FIXED BIN(15); / 精度 15 (1〜15の範囲) /
DCL VAR_P16 FIXED BIN(16); / 精度 16 (16〜31の範囲) /
DCL VAR_P31 FIXED BIN(31); / 精度 31 (16〜31の範囲) /

/ ストレージサイズ(バイト数)を変数に代因して確認 /
PUT SKIP LIST(‘— FIXED BINARY STORAGE CHECK —‘);
PUT SKIP EDIT (‘FIXED BIN( 5) のバイト数 : ‘, STORAGE(VAR_P5)) (A, F(2));
PUT SKIP EDIT (‘FIXED BIN(15) のバイト数 : ‘, STORAGE(VAR_P15)) (A, F(2));
PUT SKIP EDIT (‘FIXED BIN(16) のバイト数 : ‘, STORAGE(VAR_P16)) (A, F(2));
PUT SKIP EDIT (‘FIXED BIN(31) のバイト数 : ‘, STORAGE(VAR_P31)) (A, F(2));

END TEST_STG;

このコードの実行結果(イメージ)

このプログラムをメインフレーム上でコンパイルして実行すると、コンソールには次のように出力されます。

— FIXED BINARY STORAGE CHECK —
FIXED BIN( 5) のバイト数 : 2
FIXED BIN(15) のバイト数 : 2
FIXED BIN(16) のバイト数 : 4
FIXED BIN(31) のバイト数 : 4

見事に、`15` 以下は 2バイト(ハーフワード)、`16` 以上は 4バイト(フルワード)になっていることが分かりますね。この挙動を知っていれば、外部ファイルや他のシステムとのインターフェース設計でデータレイアウトを合わせるときにも、迷うことがなくなります。

—

5. まとめ:怖がらなくて大丈夫、PL/Iはあなたの味方です

今回は、PL/Iの `FIXED BINARY` における精度 `p` とストレージ占有量の関係について解説しました。

  • 1 〜 15 の指定なら 2バイト(ハーフワード)
  • 16 〜 31 の指定なら 4バイト(フルワード)

この基本ルールさえ頭の片隅に置いておけば、レガシーコードの海に放り出されても、もう怯える必要はありません。「あ、ここは2バイト使ってるんだな」「ここはフルワード境界を意識しているんだな」と、コードの意図がスルスルと読み解けるようになります。

メインフレームの世界は一見すると独特ですが、ハードウェアの効率と密接に結びついた非常に合理的で美しい世界です。ぜひ、一つひとつの仕様を楽しみながら、頼れるシステムアーキテクトへの道を歩んでいってくださいね!

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