「小数点がないのに小数?」PL/Iの魔法『PIC ‘V’』の秘密を解き明かす
こんにちは。メインフレームの世界へようこそ。
JavaやCOBOLでバリバリ開発してきた方にとって、初めてPL/Iのコードを見たとき「ん?なんだこの変な宣言は?」と戸惑うことはよくありますよね。
特に、PL/Iを語る上で避けて通れないのが『PIC ‘V’』という不思議な存在です。物理的にはどこにも存在しないはずの小数点なのに、計算結果はしっかり小数を維持している……。まるで手品のようなこの仕組み、実はメインフレームのアーキテクチャを知る上での一番の鍵なんです。
今日は、そんなPL/Iの「見えない小数点」の正体を、現場の視点から紐解いていきましょう。
—
そもそもPL/Iには「予約語」がない?
本題に入る前に、PL/Iのちょっと面白いルールを一つだけ。
多くの言語には「この単語はプログラムの命令だから変数名に使っちゃダメ!」という「予約語」がありますが、PL/Iには原則として予約語が存在しません。
例えば、`IF` という名前の変数を作っても、PL/Iは賢いので「ああ、これは条件分岐のIFじゃなくて、データを入れる箱(変数)のことね」と文脈から判断してくれます。自由度が高い反面、書き方によってはコンパイラを迷わせてしまうこともあるので、現場では「予約語っぽく見える名前は避ける」のが暗黙のルールになっています。
—
PIC ‘V’:実体なき「仮想小数点」の正体
さて、本題の `PIC ‘V’` です。
まずは以下のコードをご覧ください。
/ PIC ‘V’ を使った定義の例 /
DCL SALES_AMT PIC ‘9999V99’; / 全体で6桁、うち小数部が2桁 /
DCL TAX_RATE FIXED DEC(3,2); / 0.00〜9.99の範囲 /
/ 演算時の動き /
SALES_AMT = 123456; / 内部的には 1234.56 として扱われる /
なぜこれが「仮想」なのか?
COBOLなどの経験がある方はピンとくるかもしれませんが、`PIC ‘9999V99’` と宣言しても、メモリ上に「ドット(.)」という記号が書き込まれるわけではありません。
- 物理メモリ: `123456` という数字が並んでいるだけ。
- コンパイラの脳内: 「Vの場所はここだから、右から2桁目が小数点の境界線だぞ」という管理用メタデータとして保持されています。
つまり、Vは「ここに小数点がある前提で、演算や代入のときに桁合わせ(シフト)を自動でやってね」というコンパイラへの命令書なのです。
—
演算時の「位置合わせ」はどうなっている?
ここが一番のポイントです。異なる桁数や小数点位置を持つデータ同士を足し算するとき、PL/Iはどうしているのでしょうか。
例えば `123.45` と `12.345` を足す場合、人間は筆算で「小数点を揃えて」計算しますよね。PL/Iも全く同じことを、CPU内部でシフト命令を使って行っています。
DCL A PIC ‘999V99′; / 3桁.2桁 /
DCL B PIC ’99V999’; / 2桁.3桁 /
DCL C PIC ‘9999V999’;
C = A + B;
/ コンパイラは内部で以下のように補正します /
/ A: 12345 (123.45) を 123450 に左シフト /
/ B: 12345 (12.345) を 012345 に右シフト /
/ これらを足して結果を保持する /
この「自動的な桁合わせ」こそが、メインフレームが長年、金融機関の勘定系システムで信頼されてきた理由です。浮動小数点(Float)のような誤差が出やすい方式ではなく、固定小数点方式で小数点を「仮想的に管理」することで、金額計算の精度を1円単位で完全に保証しているのですね。
—
初学者が気をつけるべき「罠」
この「便利で強力なPIC ‘V’」ですが、一つだけ注意が必要です。それは「桁あふれ(オーバーフロー)」です。
`PIC ‘999V99’` の変数に `9999.00` を代入しようとすると、コンパイラや実行環境によっては「収まりきらない!」と例外が発生したり、予期せぬ切り捨てが起きたりします。
- アドバイス: プログラムを改修する際は、必ず「計算結果が収まる桁数があるか?」を再確認してください。特に、消費税計算などで `V` の位置をずらすと、それまでのロジックが根底から崩れることがあります。
—
最後に:怖がらなくて大丈夫です
PL/Iのコードを初めて見ると、その独特な記法に圧倒されるかもしれません。でも、一つずつ紐解いていけば、これほど論理的で、かつ計算精度に対して誠実な言語は他にありません。
「仮想小数点」は、ただの見えない目印です。プログラムを書きながら、「このデータの小数点は今どこにあるのかな?」と頭の中でコンパイラと同じ視点を持てれば、もうあなたはPL/I使いの仲間入りですよ。
また次回、さらに深いメインフレームの世界でお会いしましょう!
