【実務・中級編】FIXED BINARY(p,q)の精度と内部表現 – PL/Iの基本構文とデータ制御実践ガイド

「なぜ2バイトで収まるはずが?」PL/IのFIXED BINARY(p,q)とメモリ、そして演算の罠

メインフレームの現場で長年PL/Iを触っていると、「たかが数値型」と侮って痛い目を見る若手エンジニアに時折出会う。特に、移行プロジェクトでCOBOLのPIC S9(4) COMPやS9(9) COMPをPL/Iに書き換える際、`FIXED BINARY`の仕様を理解せずに定義してしまい、謎の例外終了や計算誤差に頭を抱えるケースだ。

今日は、我々が日常的に扱う`FIXED BINARY(p, q)`の内部構造と、現場で生き残るための「精度管理」について、少し掘り下げて話をしよう。

1. メモリ消費の分かれ道:2バイトか4バイトか

PL/Iにおいて`FIXED BINARY(p, q)`の精度`p`は、メモリ消費量と演算速度を決定づける重要なパラメータだ。多くのエンジニアが誤解しているが、`p`の指定によって以下の2つの境界線が存在する。

  • p=1 ~ 15 : 2バイト(HALFWORD) を消費する。
  • p=16 ~ 31 : 4バイト(FULLWORD) を消費する。

もし君が`FIXED BINARY(31)`と書けば、それは確実に4バイトを使う。ここで注意すべきは、「pの値を小さくすれば、必ずしもCPU負荷が下がるわけではない」という点だ。汎用機のアーキテクチャ上、32ビットレジスタでの演算が最適化されているため、半端に2バイトで定義すると、むしろコンパイラがロード時に符号拡張(Sign-extension)の命令を挟むことになり、効率が落ちることもある。

実務では、カウンター変数などは`FIXED BINARY(31)`で統一しておくのが、アライメントの観点からも最もトラブルが少ない。

2. 演算時のオーバーフローとONユニットの重要性

`FIXED BINARY`演算で最も恐ろしいのは、計算結果が精度`p`を超えた時に、コンパイラが「黙って切り捨てる」か、「例外を投げる」かの挙動がコンパイルオプションに依存することだ。

特にVSAMファイルからの読み込みや、レコード入出力で定義した構造体内の数値フィールドがオーバーフローを起こすと、バッチは一瞬で`SOC7`(COBOLの場合)に近い惨状を招く。これを制御するには、`ON SIZE`ユニットを適切に配置することが不可欠だ。

実践的なサンプルコード

1
TEST_CALC: PROCEDURE OPTIONS(MAIN);

/ 2バイトの限界値チェック /
DCL COUNT_VAL FIXED BINARY(15, 0) INIT(0);
DCL MAX_VAL FIXED BINARY(15, 0) INIT(32767);
DCL WORK_VAL FIXED BINARY(31, 0);

/ オーバーフロー発生時のハンドリング /
ON SIZE BEGIN;
PUT SKIP LIST(‘警告: 数値演算でオーバーフローが発生しました’);
/ ここでダンプ取得やエラーログ出力を行う /
SIGNAL ERROR;
END;

/ 意図的に限界を超える計算 /
COUNT_VAL = MAX_VAL + 1;

/ BUILTIN関数による精度の確認 /
PUT SKIP LIST(‘現在の精度: ‘ || TRIM(PRECISION(COUNT_VAL)));

END TEST_CALC;

3. VSAMアクセスと構造体マッピングの罠

マイグレーション時に特に注意してほしいのが、「コピーブック(Copybook)からの構造体定義」だ。COBOL側が`COMP`で定義されている場合、PL/I側で`FIXED BINARY`を当てる際には、`UNALIGNED`属性を明示的に指定しないと、アライメント調整のためにパディング(余分なバイト)が自動的に挿入される。

1
DCL 1 RECORD_AREA UNALIGNED,
5 KEY_FIELD CHAR(8),
5 DATA_COUNT FIXED BINARY(15, 0); / UNALIGNEDがないと予期せぬパディングが入る /

この`UNALIGNED`を忘れると、VSAMから読み込んだレコードのオフセットが後ろにズレ込み、全フィールドの読み取りが壊滅する。この手のデバッグは、後から追うと非常に骨が折れる。「構造体にはとりあえずUNALIGNED」という習慣を、今のうちに身につけておいてほしい。

まとめ:ベテランからの提言

PL/Iの`FIXED BINARY`は非常に強力だが、その「自由度」が時として保守性を下げる諸刃の剣となる。

1. 計算用ワークは原則`FIXED BINARY(31, 0)`に統一する(CPU効率とオーバーフロー回避)。
2. 構造体定義には必ず`UNALIGNED`を付け、物理レイアウトを死守する。
3. 計算ロジックには必ず`ON SIZE`ユニットを仕込み、異常系を隠蔽しない。

技術というものは、仕様を知っているだけでは足りない。その仕様が「ハードウェアのどの領域を叩いているか」を想像できるかどうかが、プロとアマの分かれ道だ。

次の改修案件でも、ソースコードの隅々まで注意を払い、堅牢なシステムを維持してくれ。健闘を祈る。

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