PL/Iの「BINARY関数」は魔法の杖?型変換の落とし穴を優しく紐解く
皆さん、こんにちは!長年、巨大なメインフレームの深淵でシステムアーキテクトをしている者です。
JavaやCOBOLの世界からやってきた皆さんにとって、PL/I(ピーエル・ワン)という言語は、まるで「何でもできるけど、少しだけ気難しい魔法使い」のように見えるかもしれません。特に、数値型の扱いには独特のルールがあって、最初は戸惑いますよね。
今日は、その中でも「数値型をFIXED BINARYに変換する」という、実務のバッチ改修で必ずと言っていいほど遭遇するテーマを深掘りしてみましょう。怖がる必要はありません。一つずつ紐解けば、実はとても論理的で美しい仕組みなんです。
—
そもそも「FIXED BINARY」って何者?
COBOLの世界でいうところの`COMP`(2進演算形式)をイメージしてください。PL/Iの`FIXED BINARY`は、コンピュータが最も好む「2進数形式」で数値をメモリに配置する型です。
計算速度が極めて速いのが特徴ですが、その代わり「どれくらいの桁数(精度)を確保するか」をコンパイラに明確に伝えてあげる必要があります。ここで登場するのが、`BINARY`ビルトイン関数です。
—
BINARY関数の基本:型変換のレシピ
`BINARY`関数は、どんな数値型(DECIMALやFLOATなど)でも、指定した精度(桁数)の`FIXED BINARY`に料理してくれる魔法の関数です。
書き方はこうです:
`BINARY(数値, 精度, スケール)`
- 数値: 変換したい元の値。
- 精度: 何ビットまで許容するか(重要!)。
- スケール: 小数点以下の桁数(整数なら省略可)。
実践的なコード例を見てみよう
/i
MAIN_PROC: PROCEDURE OPTIONS(MAIN);
/ 宣言:DECIMAL型の変数を用意 /
DCL DEC_VAL FIXED DECIMAL(5, 0) INIT(12345);
/ 変換:16ビットの精度を持つFIXED BINARYへ /
/ 第2引数の「15」が精度(ビット数)を表します /
DCL BIN_VAL FIXED BINARY(15);
BIN_VAL = BINARY(DEC_VAL, 15);
PUT SKIP LIST(‘変換結果: ‘ || BIN_VAL);
END MAIN_PROC;
—
ここがハマりポイント!「精度」と「丸め」のルール
さて、ここからが本題です。他言語経験者が一番悩むのが、「精度が足りない時、値はどうなるの?」という点ですね。
1. 精度不足は「切り捨て」か「エラー」か?
PL/Iの非常に親切(あるいは厳しい)なところは、変換時に精度が足りないと、コンパイル時または実行時に「それは収まりきらないよ!」と教えてくれる点です。
もし`FIXED BINARY(15)`(約32,767まで)という箱に、それ以上の大きな数値を無理やり詰め込もうとすると、上位ビットが溢れて、数値がとんでもない値(あるいは符号反転)に化けてしまいます。
2. 丸め挙動のヒミツ
もし、浮動小数点数(FLOAT)から`FIXED BINARY`に変換する際、小数点以下が含まれていたらどうなるでしょうか?
実は、PL/Iは「デフォルトで小数点以下を切り捨て(Truncate)」します。
四捨五入(Round)してほしい場合は、別途`ROUND`関数と組み合わせて使うのが、メインフレーム現場での「守りのコーディング」の定石です。
/i
/ 123.9 を 整数123 に切り捨てて変換する例 /
DCL FLOAT_VAL FLOAT DECIMAL(6) INIT(123.9);
DCL BIN_RESULT FIXED BINARY(15);
/ BINARY関数単体では「切り捨て」が行われる /
BIN_RESULT = BINARY(FLOAT_VAL, 15);
/ もし四捨五入したいなら、こう書くのがプロの技 /
/ ROUND関数で一旦整数に丸めてからBINARYに渡す /
BIN_RESULT = BINARY(ROUND(FLOAT_VAL, 0), 15);
—
アーキテクトからのアドバイス:怖がらないで!
PL/Iの型変換が難しく感じるのは、「コンピュータのメモリの形」を意識しなければならないからです。でも、裏を返せば、「どのようにメモリを確保し、どのように計算させるか」をプログラマが完全に制御できるという、非常に強力なメリットでもあります。
- 精度指定(ビット数)は、その変数が扱う「最大値」をしっかり見極めて決めること。
- 変換時は、切り捨てか四捨五入かを明示的に意識すること。
この2点さえ押さえておけば、皆さんのバッチプログラムは、何十年先まで動き続ける堅牢なコードになりますよ。
「PL/Iって難しそう…」と思っていたあなたの心が、少しでも軽くなれば嬉しいです。もしまた変換のルールで迷ったら、いつでもここに戻ってきてくださいね。一緒に紐解いていきましょう!
