PL/IからJavaへ。メインフレームの「数字」が引き起こす、愛すべき(そして厄介な)落とし穴
こんにちは!メインフレームの世界へようこそ。
長年、銀行や保険会社の心臓部を支えてきた「PL/I」。JavaやPythonを触ってきた皆さんから見ると、その文法は少しばかり古風で、時に摩訶不思議に見えるかもしれません。
特に、データ移行の現場で最もエンジニアを悩ませるのが、「数値の扱いの違い」です。今日は、PL/Iの頑固な数値定義と、Javaの柔軟な数値処理を橋渡しする際、絶対に知っておくべきポイントを紐解いていきましょう。
—
1. PL/Iの「FIXED DECIMAL」という強固な城壁
Javaで金額を扱うとき、皆さんは迷わず`BigDecimal`を使いますよね? PL/Iでは、これに相当するのが`FIXED DECIMAL`という属性です。
PL/Iの数値宣言は、まるで設計図のように厳格です。
/i
/ 合計金額を定義する例 /
DCL TOTAL_AMT FIXED DECIMAL(15, 2);
/ 全体で15桁、そのうち小数点以下が2桁という意味 /
この`(15, 2)`という指定が曲者です。PL/Iはこれをコンパイルした時点で、メモリ上の領域を「計算機が効率的に処理できる形」で厳密に確保します。
なぜJavaへの移行で事故が起きるのか?
Javaの`BigDecimal`は、必要に応じて桁数が伸び縮みする「可変」の側面を持っています。しかし、PL/Iの`FIXED DECIMAL`は「溢れたら切り捨てる、あるいは例外を飛ばす」という固定的なルールで動いています。
移行先のJavaで、もし`double`型などを使って「なんとなく計算」してしまうと、精度の欠落(丸め誤差)が必ず発生します。金融システムで0.01円の誤差が出れば、それは「バグ」ではなく「事件」ですよね。
—
2. ピクチャ属性(PICTURE)の魔術
PL/Iには、数値の表示形式を直接定義する`PICTURE`(通称:PIC)という強力な機能があります。
/i
DCL DISP_AMT PIC ‘ZZZ,ZZZ,9V.99’;
/ Zは先行ゼロ抑制、Vは小数点の位置を示す仮想的な目印 /
この`V`(Scaling Factor)が初学者の皆さんを最も困惑させます。「え、そこに小数点があるの?でもデータ自体にはドットは入っていないの?」と。
実は、PL/Iの内部データ表現では、`V`の位置は「概念上の場所」であり、物理的にドットコードが入っているわけではありません。Javaでこれを受け取るとき、単に文字列として扱うのか、数値として扱うのかを明確にしないと、「見えない小数点の位置」を読み違えて、金額が100倍になったり1/100になったりするという、悲しい事故が起きてしまうのです。
—
3. 実践:マイグレーション時の「安全な」マッピング
Javaへ移行する際、以下の「鉄の掟」を意識してください。
① 数値型は必ず `java.math.BigDecimal` を使う
`float`や`double`は、たとえテスト環境でうまくいったように見えても、将来的に必ず足元をすくわれます。`BigDecimal`のコンストラクタには、必ず`String`で値を渡すのが定石です。
② ピクチャ属性の「V」を正しく解釈する
PL/Iで`PIC ‘999V99’`となっている変数は、Java側では「値を100で割ったもの」として`BigDecimal`に格納する必要があります。
// PL/Iの PIC ‘999V99’ (例: 12345) をJavaで扱う場合
String pliValue = “12345”;
BigDecimal javaValue = new BigDecimal(pliValue).divide(new BigDecimal(“100”));
// これで正しく 123.45 として扱えます
—
4. 最後に:怖がる必要はありません
PL/Iは確かに古い言語ですが、その挙動は非常に「正直」です。コンピュータの都合を隠さず、プログラマに「どういうデータ構造なのか」を明示させることを求めてきました。
Javaへのリプレイスは、単なるコードの書き換えではありません。「メインフレームが長年守ってきた厳格な数値のルール」を、現代の柔軟なアーキテクチャに翻訳する作業です。
「データはどこまで厳密であるべきか?」
この問いを常に持ち続けることこそが、優秀なシステムアーキテクトへの第一歩です。わからないことがあれば、いつでも聞いてくださいね。現場の知見を総動員して、あなたのマイグレーションプロジェクトを成功へ導くお手伝いをしますから。
それでは、また次回のレガシー探訪でお会いしましょう!
