【入門編】FIXED BINARYのオーバーフローとON FIXEDOVERFLOW – PL/Iの基本構文とデータ制御実践ガイド

こんにちは!メインフレームの世界へようこそ。
JavaやCOBOLといったモダン、あるいはビジネスの現場でバリバリ活躍されている言語をご存知の方にとって、IBMメインフレームの「PL/I(ピーエルアイ)」という名前は、少し古めかしく、どこか近寄りがたいダンジョンのように感じられるかもしれませんよね。

「なんだか変数の宣言が独特だし、記号の意味も難解そう……」
「いきなり本番機で異常終了(ABEND)したらどうしよう……」

そんな風に不安を抱えていらっしゃるあなたへ。大丈夫です、安心してください。今日は、PL/Iの数ある特徴の中でも、特に基幹システムの計算処理で避けて通れない「FIXED BINARYのオーバーフロー」と、それを優しく包み込んでハンドリングする「ON FIXEDOVERFLOW」の仕組みについて、一緒に紐解いていきましょう。

1. 他言語とはココが違う!PL/Iのユニークな変数命名と「予約語がない」世界

JavaやCOBOLには、たくさんの「予約語(IFやMOVEなど、システムが特別な意味で使うから変数名には使えない単語)」がありますよね。例えばCOBOLで `COMPUTE` という名前の変数を作ろうものなら、コンパイラに怒られてしまいます。

ところが、PL/Iの面白い(そして少しビックリする)ところは、「PL/Iには原則として予約語が存在しない」という点です。

どういうことかと言うと、極端な話、以下のようなコードを書くことも理論上は可能です。

1
/ IFという名前の変数を宣言して、それにIFを代入するようなカオスも…… /
DCL IF FIXED BIN(31);

「えっ、じゃあコンパイラはどうやって `IF` が条件分岐なのか、変数なのかを見分けているの?」と思いますよね。
これは、PL/Iのコンパイラが前後の文脈(コンテキスト)を非常に賢く読み取っているからなんです。人間と同じように、「あ、この位置にある `IF` はキーワードだな、こっちは変数だな」と空気を読んでくれます。

とはいえ、実務の現場でこんなトリッキーな命名をする人はいませんのでご安心を(笑)。ただ、「キーワードに縛られすぎず、柔軟に名前をつけられるんだな」と、肩の力を抜いていただければと思います。

2. FIXED BINARYってなに?(怖くないデータ型の正体)

さて、本題の「FIXED BINARY」に進みましょう。
COBOLerの皆さんなら `COMP-3`(パック十進数)や `BINARY`、Javaerの皆さんなら `int` や `long` をイメージしてもらうと近いです。

PL/Iにおける `FIXED BINARY(固定小数点二進数データ)` は、メインフレームのCPUが最も得意とする、いわば「計算の優等生」です。

1
DCL 売り上げ金額 FIXED BIN(31) ;

この `FIXED BIN(31)` という宣言、初見だと「31桁の数字が入るの!?」と思ってしまいがちですが、ここが大きな罠であり、他の言語経験者がハマりやすいポイントです。

  • (31) が意味するもの:これは「10進数の桁数」ではなく、「2進数のビット数(長さ)」を表しています。
  • 扱える数値の範囲:符号付き(プラスもマイナスも扱える)の場合、31ビットのうち1ビットがプラスマイナスの符号に使われます。そのため、残りの30ビットで表現できる最大の数字は、おおよそ 約21億(2の30乗 – 1) までとなります。

「21億あれば、日々の売上管理くらい余裕でしょ!」
そう思って油断していると、ある日突然、バッチ処理が不気味なエラーメッセージを残してクラッシュします。それが、今回の主役であるオーバーフローです。

3. 計算結果がキャパオーバー!FIXEDOVERFLOWの恐怖

例えば、全国展開する巨大スーパーの売上集計バッチを作っているとしましょう。
各店舗の売上をどんどん足し算していき、最終的な全社売上を計算する変数に格納しようとしたとき、その合計値が「2,147,483,647(約21億)」をほんの1円でも超えてしまったら……?

CPUはパニックを起こします。
「あれっ? 31ビットの箱に入り切らないよ! あふれちゃうよ!」

これが FIXEDOVERFLOW(固定小数点数オーバーフロー) です。
何の対策もしないままこの状態を放置すると、プログラムは容赦なく異常終了(システムABEND)を引き起こし、夜間バッチの運用担当者から青ざめた顔で内線電話がかかってくることになります。

4. 救世主登場!「ON FIXEDOVERFLOW」で優しく受け止める

「じゃあ、21億を超える可能性があるなら、全部もっと大きいデータ型(例えば `FIXED DEC` や 浮動小数点)に変えなきゃいけないの?」

いいえ、必ずしもそうとは限りません。
PL/Iには、もしオーバーフローが発生してしまった時に、「プログラムを即死させるのではなく、私(プログラマ)に処理を任せて!」と宣言できる、非常にエレガントで強力な仕組みが用意されています。

それが ON条件(例外処理機構) です。

実際のコード例を見てみましょう。

1
————————————————————–

  • FIXED BINARYのオーバーフローをキャッチするサンプルプログラム

————————————————————–
OVERFLOW_SAMPLE: PROC OPTIONS(MAIN);

/ 変数の宣言:31ビットのFIXED BINARY /
DCL 予算残高 FIXED BIN(31) INIT(2147483640); / もうすぐ限界値 /
DCL 追加費用 FIXED BIN(31) INIT(100); これを足すと21億オーバー!
DCL 結果 FIXED BIN(31);

/

  • 【重要】FIXEDOVERFLOWが発生したときの「身代わり処理」を定義する

/
ON FIXEDOVERFLOW
BEGIN;
DISPLAY(‘【警告】計算結果が許容範囲を超えました!安全値に丸めます。’);

/ ここで強制的に最大値を代立させるなどのリカバリが可能 /
結果 = 2147483647;

/ 処理を続行させるためのGOTO(例外処理の復帰) /
GOTO CONTINUE_LBL;
END;

/ — 実際にオーバーフローが起きる計算を実行 — /
DISPLAY(‘計算を開始します…’);
結果 = 予算残高 + 追加費用;

/ 通常はここを通るが、オーバーフロー時はONブロックからジャンプしてくる /
CONTINUE_LBL:

DISPLAY(‘最終結果(安全化処理後) = || 編集(結果, ‘999,999,999,999’);’);

DISPLAY(‘プログラムを正常に終了します。’);

END OVERFLOW_SAMPLE;

このコードのポイント

1. `ON FIXEDOVERFLOW BEGIN; … END;`
このブロックを記述しておくだけで、万が一プログラム内でデータがあふれ返っても、システムが勝手に強制終了(ABEND)させるのを防ぎ、自前のリカバリコードに処理をバトンタッチさせることができます。
2. 安全なフォールバック
「もしあふれたら、とりあえずエラーフラグを立てて最大値をセットし、処理自体は最後まで走り切らせる」といった、夜間バッチの止められない基幹システムにおいて非常に有効な処置が取れます。

5. 根本的な解決:最初から大きな箱を用意するスマートなアプローチ

`ON FIXEDOVERFLOW` は素晴らしい防衛策ですが、毎回の計算で例外処理を走らせるのは、パフォーマンスの観点やロジックの複雑化を招く原因にもなります。

もし初めから「あきらかに21億を超えることが分かっている」「安全性を高めたい」という場合は、データ宣言そのものを拡張するのがモダンなプログラマの選択です。

  • より大きなバイナリ型にする
  • `FIXED BIN(31)` の代わりに、63ビット(符号付き)を扱える `FIXED BIN(63)` を使えば、約900京という途方もない数字まで扱えるようになります。
  • 固定小数点十進数(PACKED DECIMAL)を使う
  • COBOLの `COMP-3` に相当する `FIXED DECIMAL`(PL/Iでは `FIXED DEC` と略すことも多いです)を使用します。これは桁数を明示的に指定でき(例: `FIXED DEC(15, 2)` なら全体で15桁、うち小数点が2桁)、金融計算などで誤差を出したくない場合に大活躍します。

1
/ 金融や大規模な金額計算ではこちらが安心 /
DCL 巨大な売上総額 FIXED DEC(15, 2) INIT(0);

おわりに:レガシーの世界も、怖くない!

いかがでしたでしょうか?
「PL/I」「FIXED BINARY」「オーバーフロー」といった専門用語の並ぶ世界も、蓋を開けてみれば、他の言語と同じように「変数のサイズ制限があって、それをどう扱うか」という非常にシンプルなロジックの積み重ねであることがお分かりいただけたかと思います。

メインフレームの仕組みは、何十年もの歴史の中で洗練されてきた分、非常に堅牢で合理的です。「レガシーだから難解だ」と身構えず、一つひとつのデータ属性と対話するようにコードを紐解いていけば、必ずあなたの強力な武器になります。

日々のマイグレーションや保守作業、本当にお疲れ様です。
あなたのメインフレームライフが、少しでも快適で楽しいものになりますように!

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