PL/Iの「型」でハマらないために:FIXED BINARY(15)と(31)の深淵と実用
こんにちは。メインフレームの迷宮へようこそ。
JavaやCOBOLから来た皆さんにとって、PL/Iのデータ宣言は時に「なぜこんなに種類があるの?」という驚きをもたらすかもしれません。今日は、その中でも特にバッチ処理のパフォーマンスと「うっかりミス」に直結する、`FIXED BINARY`(固定小数点2進数)についてお話しします。
「数字を入れる箱」なら全部同じじゃないの? と思うなかれ。メインフレームの世界では、この「箱のサイズ」がCPUの機嫌を左右するのです。
—
FIXED BINARY(15)と(31)の正体
まず、この括弧の中の数字は何を意味しているのでしょうか。結論から言えば、「ビット数(符号を含む)」です。
- FIXED BINARY(15):2バイト(16ビット)の箱。俗に言う「ハーフワード」。
- FIXED BINARY(31):4バイト(32ビット)の箱。俗に言う「フルワード」。
なぜ(16)や(32)ではないのか? それはPL/Iが「符号ビット」を厳密に扱う言語だからです。15ビット分を数値として使い、残り1ビットを符号(プラスかマイナスか)に充てる。だから15なのです。
CPUレジスタへのロード効率の話
メインフレームのCPU(z/Architecture)は、実は4バイト(フルワード)単位での処理が最も得意です。
もし皆さんが`(15)`を指定すると、CPUは「お、小さい箱だな。じゃあわざわざ符号を拡張してフルワードに合わせる(符号拡張)処理をしてから計算しよう」と、余計なひと手間をかけてしまいます。これが塵も積もれば山となり、何百万件ものレコードを処理するバッチでは、無視できない計算コストの差となって現れるのです。
—
実践:PL/Iで書いてみよう
では、実際にプログラムの断片を見てみましょう。
/i
TEST_PROC: PROCEDURE OPTIONS(MAIN);
/
- FIXED BINARY(15)は、メモリを節約したい構造体のメンバ等では有効ですが、
- 単純なカウンタにはFIXED BINARY(31)を推奨します。
/
DCL COUNT_SMALL FIXED BINARY(15) INIT(0); / ハーフワード:最大値は32767 /
DCL COUNT_LARGE FIXED BINARY(31) INIT(0); / フルワード:約21億までOK /
/ 演算の例 /
COUNT_LARGE = COUNT_LARGE + 1;
/
- ここで注意!もし(15)の箱に32767を超える値を入れると、
- エラー(FIXEDOVERFLOW)が発生し、プログラムが異常終了します。
/
COUNT_SMALL = 32767 + 1;
END TEST_PROC;
—
「オーバーフロー」は突然やってくる
Javaの`int`であれば、オーバーフローしても丸め込まれて負の数になるだけかもしれませんが、PL/Iのデフォルト設定では「計算が合わない」ことを極端に嫌います。
もし`(15)`の変数に収まりきらない値を放り込むと、メインフレームは即座に「演算例外」を投げてプログラムを停止させます。これは恐ろしいことのように聞こえますが、実は「データの間違いを早期に発見できる」という、基幹システムを守るための安全装置なのです。
初学者へのアドバイス
1. 迷ったら(31)を使う: 最近のメモリ事情であれば、ケチケチして(15)を使うよりも、計算速度と安全性を優先して(31)を使うのが現代のメインフレーム開発の定石です。
2. 意味のある宣言を: もしDBから読み込んだデータが「フラグ」や「非常に小さな値」であることが確定しているなら、(15)を使うことはメモリ節約として正しい選択です。
—
最後に:怖がる必要はありません
PL/Iのデータ宣言は、最初は複雑に見えますが、それはすべて「ハードウェアの性能を極限まで引き出し、データ整合性を担保するため」に設計された知恵の結晶です。
「なぜ(15)なのか?」という疑問を持った時点で、あなたはもう立派なメインフレームエンジニアの卵です。次にコードを書くときは、ぜひ「この変数は何のために存在するのか?」「計算速度は十分か?」と、変数の箱に語りかけてみてください。
もし計算の挙動で悩んだら、またいつでもここへ来てくださいね。現場の知見を詰め込んで、また解説しますから。それでは、良きメインフレームライフを!
