【入門編】LOGおよびEXP関数の数学ライブラリ呼び出し – PL/Iの基本構文とデータ制御実践ガイド

こんにちは!メインフレームの世界へようこそ。
JavaやCOBOLといったモダンな、あるいはビジネスの現場でお馴染みの言語をご経験された方にとって、IBMメインフレームの「PL/I(ピーエルアイ)」は、少しおどろおどろしい、あるいはタイムカプセルから出てきたような異質な言語に見えるかもしれません。

「変数名のルールはどうなっているんだろう?」
「なんだか見慣れない書き方が多いな……」

ご安心ください。怖がる必要は全くありません。今回は、PL/Iのちょっとユニークな識別子のルールにふれつつ、数学ライブラリの心臓部である`LOG`(対数)と`EXP`(指数)の関数が、あの巨大なメインフレームの内部でどうやって計算され、精度を保っているのかを、そっと紐解いていきたいと思います。

—

1. そもそもPL/Iの変数名って、自由に決めていいの?

JavaやCOBOLを触ってきた方だと、「このキーワードは予約語だから変数名に使えない!」という壁に何度もぶつかったことがあるのではないでしょうか。COBOLなんて、動詞や句がそのまま予約語になっているので、名前付けに苦労しますよね。

ところが、PL/Iには「予約語」という概念が基本的に存在しません。

「えっ、じゃあ `IF` とか `THEN` って変数名にしても怒られないの?」

驚かれるかもしれませんが、PL/Iのコンパイラは非常に賢く(そして少しお節介に)、「文脈(コンテキスト)」でそれを判断します。

1
/ PL/Iのちょっとびっくりな変数宣言の例 /
DCL IF FLOAT; / なんと ‘IF’ という名前の浮動小数点変数 /
DCL THEN FLOAT; / ‘THEN’ という名前の変数 /

IF = EXP(2.0); / 変数IFに、EXP関数の計算結果を代入している /

コンパイラは、「ここで出てきた `IF` は、直前の文脈から見て変数だな」と瞬時に理解するため、エラーになりません。もちろん、コードを読む人間のメンタルヘルスを保つために、あえて `IF` や `THEN` を変数名にするのは避けるべきですが、「言語仕様として予約語に縛られない」という柔軟性を持っています。

識別子自体のルールはシンプルで、

  • アルファベット、数字、国別文字(`@`, `#`, `$` など)が使えます。
  • 長さは最大31文字まで。
  • 先頭は必ず文字(または国別文字)で始める必要があります(数字から始めるのはNGです)。

Javaのようにキャメルケースで書くこともできますが、伝統的なメインフレームの現場では、大文字とアンダースコア(`_`)を使った `TOTAL_AMOUNT` のようなスタイルが愛されています。

—

2. 数学ライブラリの裏側:LOG関数とEXP関数はどう動いている?

さて、本題の数学ライブラリのお話です。
業務アプリケーションで金利計算や統計処理、あるいは複雑な工学計算を行う際、自然対数を求める `LOG` や、その逆である自然対数の底($e$)のべき乗を求める `EXP` は欠かせない存在ですよね。

Javaの `Math.log()` や `Math.exp()` は、JVM(Java仮想マシン)の背後でOSやCPUのネイティブ命令を叩いています。では、PL/Iの場合はどうなっているのでしょうか?

PL/Iで書かれた `LOG` や `EXP` を実行すると、プログラムはIBMメインフレームの実行時ライブラリである `SCEELKED`(Language Environmentのライブラリ) の中にある、高度に最適化された数学ルーチンを呼び出します。

内部で何が行われているのか?

メインフレームのハードウェア(Zファミリのプロセッサ)は、浮動小数点演算において世界最高峰の精度を誇ります。しかし、超越関数(指数や対数)をCPUの1命令だけでパッと正確に出すのは、実は数学的にかなり大変なことです。

そのため、実行時ルーチンは内部で以下のようなプロセスをたどっています。

1. 引数の範囲縮約(Range Reduction):
例えば `EXP(1000.0)` のような大きすぎる値や、逆に極端な小数が渡されたとき、そのまま計算するとオーバーフローや精度の桁落ちを起こします。ルーチンはまず、計算しやすい安全な範囲に数値をスケーリングします。
2. 多項式近似 / ミニマックス近似:
テイラー展開などをベースにしつつ、メインフレームの浮動小数点レジスタ(倍精度 `FLOAT BINARY(53)` や 4倍精度 `FLOAT BINARY(109)`)の精度を極限まで引き出すための特殊な係数テーブルを使って、一瞬で近似値を算出します。
3. ビット単位の丸め処理:
IEEE 754規格(またはIBM独自の16進浮動小数点数体系、※移行期や設定によります)に基づき、最後の1ビットの狂いもないよう厳密に丸めを行って値を返します。

つまり、私たちが何気なく書いた 1行の `LOG` や `EXP` の裏側では、IBMが何十年もかけて磨き上げてきた超高速・高精度な数学エンジンがフル稼働しているというわけです。

—

3. 実践!PL/Iで書くLOG・EXPのコード例

百聞は一見にしかず。実際にPL/Iで `LOG` と `EXP` を使ったプログラムを見てみましょう。
COBOLやJavaをご存知の方なら、すぐに「あ、こういうことね」と直感していただけるはずです。

1
————————————————————–;

  • 投資シミュレーションを想定した数学関数(LOG/EXP)の利用例

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

/ 変数の宣言:IEEE倍精度浮動小数点数(FLOAT DEC(16) はJavaのdoubleに近いイメージです) /
DCL INITIAL_CAPITAL FLOAT DEC(16) INIT(10000.0); / 元本: 10,000円 /
DCL INTEREST_RATE FLOAT DEC(16) INIT(0.05); / 年利: 5% (0.05) /
DCL YEARS FLOAT DEC(16) INIT(10.0); / 運用年数: 10年 /

DCL FUTURE_VALUE FLOAT DEC(16); / 複利後の金額 /
DCL RECON_YEARS FLOAT DEC(16); / 逆算した年数 /

PUT SKIP LIST(‘=== PL/I 数学ライブラリ(LOG/EXP) デモ ===’);

/ 1. EXP関数を使った複利計算(元本 e^(rate years) は連続複利のイメージ) /

  • 厳密には離散複利なら (1+r)^t ですが、ここではEXPのデモとして連続複利モデルを使用します

FUTURE_VALUE = INITIAL_CAPITAL EXP(INTEREST_RATE YEARS);

PUT SKIP EDIT (’10年後の連続複利運用額: ‘, FUTURE_VALUE)
(A, F(12, 2));

/ 2. LOG関数を使った逆算(いくらになったら何年経っているか?) /

  • 運用額から逆に何年経過したかをLOGを使って算出します
  • 公式の変形: YEARS = LOG(FUTURE_VALUE / INITIAL_CAPITAL) / INTEREST_RATE

RECON_YEARS = LOG(FUTURE_VALUE / INITIAL_CAPITAL) / INTEREST_RATE;

PUT SKIP EDIT (‘逆算された運用年数 : ‘, RECON_YEARS)
(A, F(6, 2));

END MATH_SAMPLE;

コードのポイント解説

  • `FLOAT DEC(16)`: 10進数ベースの倍精度浮動小数点数です。金融計算などで誤差をシビアにコントロールしたいときによく使われます。Javaの `BigDecimal` ほど厳密ではありませんが、通常の科学技術計算や統計には十分すぎる精度を持ちます。
  • `INIT(10000.0)`: 変数宣言と同時に初期値を代入できる、PL/Iの非常に便利な構文です(COBOLだと `VALUE` 句、Javaだと宣言時の代入に相当します)。
  • `PUT SKIP EDIT (…) (…)`: COBOLの `DISPLAY` やJavaの `System.out.println` に相当しますが、PL/Iは出力フォーマット(画像編集句、上の例では `F(12, 2)` など)を詳細に指定できるのが特徴です。

—

まとめ:レガシーの怖さは「知らないこと」だけ

いかがでしたでしょうか?
「PL/I」という名前や、メインフレーム特有の硬質な響きに最初は身構えてしまったかもしれませんが、紐解いてみれば他のプログラミング言語と本質的な考え方は何ら変わりません。

識別子に予約語がないという自由度の高さや、`SCEELKED` ライブラリが裏側で支える堅牢な数学演算の世界を知ることで、レガシーシステムに対する見方が少しだけ温かいものに変わっていたら嬉しいです。

マイグレーションや保守の現場でPL/Iに出会ったら、「あぁ、裏でIBMのすごい数学エンジンが頑張ってくれているんだな」と思い出しながら、一つずつコードを紐解いていってくださいね。あなたのメインフレームの旅を、心から応援しています!

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