「なぜ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`ユニットを仕込み、異常系を隠蔽しない。
技術というものは、仕様を知っているだけでは足りない。その仕様が「ハードウェアのどの領域を叩いているか」を想像できるかどうかが、プロとアマの分かれ道だ。
次の改修案件でも、ソースコードの隅々まで注意を払い、堅牢なシステムを維持してくれ。健闘を祈る。
