こんにちは。メインフレームの世界へようこそ。
Javaの`int`やCOBOLの`PIC S9(9) COMP`に慣れている方にとって、PL/Iの`FIXED BINARY`(以下、FIXBIN)は少しだけ「気難しい隣人」のように感じるかもしれません。でも大丈夫、彼らの性格さえ理解してしまえば、これほど頼りになる相棒はいません。
今日は、基幹システムの現場で誰もが一度は冷や汗をかく「FIXED BINARY(15)と(31)の境界線」について、現場の知見を交えて紐解いていきましょう。
—
1. FIXED BINARYってそもそも何者?
PL/Iにおいて、`FIXED BINARY`は「2進整数」を意味します。Javaでいうところの`short`や`int`ですね。しかし、PL/Iが面白いのは「ビット単位で精度を指定できる」という点です。
- FIXED BINARY(15): 16ビット(2バイト)の領域を使います。符号ビットを含めて16ビットです。
- FIXED BINARY(31): 32ビット(4バイト)の領域を使います。メインフレームの標準的なレジスタサイズにフィットします。
「なぜわざわざ(15)とか(31)なんて中途半端な数字を書くの?」と思いますよね。これは、システムが扱うデータの「器」を最小限のメモリでやりくりするためです。昔のメインフレームではメモリは宝石のように貴重でした。その名残が、今もこうしてコードの中に生きているんです。
—
2. 内部表現の「境界線」に潜む罠
さて、ここからが本題です。この「15」と「31」の数字、実は単なるメモリサイズの指定ではありません。「どこまで安全に計算できるか」という限界点を意味しています。
FIXED BINARY(15)の限界
15ビットの精度ということは、符号を除いた15ビット分、つまり`2^15 – 1 = 32,767`が最大値です。
もし計算結果が32,768を超えるとどうなるか?…そう、オーバーフローです。
FIXED BINARY(31)の限界
31ビットの精度なら、`2^31 – 1 = 2,147,483,647`まで扱えます。
基幹システムのバッチ処理で金額計算をする際、(15)で宣言しているのに、ある日突然売上が跳ね上がって「ABEND(異常終了)」を引き起こす…というのは、現場でよくある「苦い思い出」の典型です。
—
3. 実践:コードで見る「オーバーフロー」の恐怖
実際に、どのようなコードが危険なのかを見てみましょう。
1
TEST_CALC: PROC OPTIONS(MAIN);
/ 15ビットの箱を用意(最大32,767まで) /
DCL COUNT_S FIXED BINARY(15) INIT(32000);
/ 31ビットの箱を用意(余裕たっぷり) /
DCL COUNT_L FIXED BINARY(31) INIT(32000);
/ 32,000 + 1,000 = 33,000。15ビットでは溢れます /
COUNT_S = COUNT_S + 1000;
/
- ここでシステムは「ONCONDFITION」を発生させるか、
- 最適化の設定によっては黙って不正な値を保持し続けます。
- 現場ではこの「黙って計算する」のが一番怖いのです。
/
PUT SKIP LIST(‘Sの計算結果:’, COUNT_S);
COUNT_L = COUNT_L + 1000;
PUT SKIP LIST(‘Lの計算結果:’, COUNT_L);
END TEST_CALC;
なぜ(15)を使いたがるのか?
「じゃあ全部(31)にすれば安全じゃない?」と思われるかもしれません。正解です。現代のアーキテクチャでは、メモリをケチって(15)を使うメリットはほとんどありません。
しかし、古いプログラムには「構造体(STRUCTURE)」の中で、他システムとのインターフェース定義として(15)がガチガチに固定されているケースが山ほどあります。これに触れるときは、「今の計算ロジックで最大値を超えないか」を、必ず机上でシミュレーションしてください。
—
4. コンパイラ最適化の「余計な親切」
PL/Iのコンパイラは非常に優秀です。あなたが書いたコードを、実行時に最も速い命令セット(レジスタ演算)に変換しようとします。
ここで注意したいのが、「中間計算」です。
`(A + B) C` という計算をする際、PL/Iは中間結果を一時的に高い精度(31ビットなど)で保持して計算し、最後に代入先の宣言精度に合わせて値を丸めるという挙動をとることがあります。
「いや、俺は15ビットの結果が欲しいんだ!」と思っていても、コンパイラが「いや、31ビットで計算した方が速いし正確だから」と気を利かせることがあるのです。この挙動の違いを理解していないと、「テスト環境では動いたのに、本番の最適化オプションでコンパイルしたら結果が微妙にズレた」という怪奇現象に出会うことになります。
—
最後に:怖がる必要はありません
PL/Iの宣言は、いわば「データの設計図」です。
- 「この変数は絶対に32,767を超えない」と断言できるなら、(15)を使ってメモリを節約する。
- 「将来的にどれだけ増えるか分からない」なら、迷わず(31)を使う。
これさえ守れば、PL/Iは非常に堅牢で信頼できる言語です。メインフレームでの仕事は、こうした「目に見えない箱の大きさ」を意識する、職人のような繊細な作業の連続です。
もしコードを読んでいて「ここの精度、本当に大丈夫かな?」と不安になったら、その直感は正しいです。ぜひ、その宣言の裏側にある「データの最大値」を一度計算してみてくださいね。
それでは、また次回のレガシー探訪でお会いしましょう!
