メインフレームの世界へようこそ。JavaやCOBOLという素晴らしい言語を使いこなしてきたあなたにとって、PL/Iの最初の印象は「なんて自由で、そして少しだけ掴みどころのない言語なんだろう」といったところかもしれません。
今日は、そんなPL/Iの奥深い世界から、「なぜ同じ数値計算なのに、属性一つでパフォーマンスや挙動が劇的に変わるのか?」という、ベテランでも時折ハマる「FIXED BINARY」の深淵を紐解いていきましょう。
—
1. PL/Iには「予約語」が存在しない?その衝撃の真実
まず、他言語から来た方が最初に驚くのが、「PL/Iには明確な予約語がない」という点です。例えば、Javaなら`int`や`if`は変数名に使えませんが、PL/Iでは極端な話、以下のようなコードも書けてしまいます。
1
/ PL/Iの不思議な世界 /
DECLARE IF FIXED BINARY(15) INITIAL(10);
DECLARE THEN FIXED BINARY(15) INITIAL(20);
IF = THEN + 5; / なんと変数名として動作する /
「え、コンパイラはどうやって判断しているの?」と不安になりますよね。実はPL/Iコンパイラは、文脈(コンテキスト)を見て「これはキーワードか、それとも変数か」を判断する、非常に賢い(そして気難しい)頭脳を持っているのです。最初は違和感があるかもしれませんが、これは「言語設計者が、プログラマの自由を最大限に尊重した」という歴史の遺産。怖がらず、ルールさえ守れば、PL/Iはあなたの忠実な相棒になってくれます。
—
2. FIXED BINARY(15) vs (31):ハーフワードとフルワードの戦い
さて、今回の本題です。PL/Iで数値を扱う際、`FIXED BINARY(15)`と`(31)`を使い分けることになりますが、これらは単なる桁数の違いではありません。CPU内部で起きている「物理的な差」なのです。
なぜ(15)と(31)なのか?
- FIXED BINARY(15):2バイト(16ビット)=「ハーフワード」として扱われます。
- FIXED BINARY(31):4バイト(32ビット)=「フルワード」として扱われます。
現代のIBM z/Architectureにおいて、CPUはフルワード(32ビット)やダブルワード(64ビット)の演算を最も得意とします。
パフォーマンスのリアル
「メモリを節約したいから」と安易に`(15)`を選ぶと、実は逆効果になることがあります。CPUが16ビットの演算を行う際、わざわざ32ビットのレジスタに合わせて値を詰め直したり、符号拡張(Sign extension)という処理を挟んだりするコストが発生する場合があるのです。
一方で、`(31)`はCPUのネイティブな演算サイズに合致しているため、計算が最もスムーズに進みます。迷ったら`(31)`にしておくのが、現代のメインフレームにおける「パフォーマンスの最適解」と言えるでしょう。
—
3. 恐怖のオーバーフロー:そのとき何が起きるか
一番気をつけたいのが、計算結果が属性の限界を超えたときです。
1
/ 属性の限界を超えた計算の例 /
DCL SHORT_NUM FIXED BINARY(15) INIT(32767); / (15)の最大値は約3.2万 /
DCL LONG_NUM FIXED BINARY(31) INIT(0);
/ ここで計算すると… /
LONG_NUM = SHORT_NUM + 1;
`(15)`の最大値は`32,767`です。ここに`1`を加えると、当然ながら溢れますよね。Javaなら例外が飛ぶところですが、PL/Iではコンパイル・オプション次第で、「何も言わずに変な値(異常値)を代入する」という、もっとも恐ろしい挙動をとることがあります。
これを防ぐためには、以下のようにコンパイラに「厳しく見張らせる」ことが不可欠です。
1
/ コンパイラへの指示:オーバーフローを検知したら教えてね /
/ PROCESS オプションで指定することが一般的です /
/ ON OVERFLOW 構文を使ってエラーハンドリングを仕込むことも可能です /
ON OVERFLOW BEGIN;
PUT SKIP LIST(‘警告: 数値が溢れました!’);
END;
—
最後に:怖がらなくて大丈夫です
「変数の名前が予約語と被るかもしれない」「数値が溢れると黙って異常値になるかもしれない」。そう聞くとPL/Iは危ない言語に思えるかもしれません。
しかし、PL/Iは「プログラマが明示的に制御すれば、究極のパフォーマンスを叩き出せる」という、エンジニアの意志を尊重する言語です。Javaの快適さとは違う、機械の息遣いを感じられるような「ダイレクトな制御」の楽しさがここにあります。
まずは`(15)`と`(31)`の使い分けから、メインフレームのCPUと対話する感覚を掴んでみてください。何か詰まったら、いつでもここで紐解いていきましょうね。あなたのレガシー移行プロジェクトが、最高の結果になることを応援しています。
