PL/Iの「ピクチャ編集」を恐れるな! `9`と`Z`で操る数値の魔法
こんにちは。メインフレームの世界へようこそ。
JavaやCOBOLでバリバリ開発してきた皆さんにとって、PL/Iのコードを初めて開いた時、「なんだこの記号の羅列は?」と面食らうことはよくありますよね。
特に、データ宣言の横に書かれた `PIC ‘ZZZ,ZZ9’` のような記述。COBOLの経験がある方は「ああ、あれね」とピンとくるかもしれませんが、PL/Iのピクチャ編集は少しばかり「クセ」が強いんです。今日は、この数値編集の基本を、現場の知恵を交えて紐解いていきましょう。
—
数値編集の「お約束」:ピクチャ文字とは?
PL/Iにおいて、数値は内部的にはバイナリやパック十進数で保持されています。しかし、帳票や画面に出力する際には、人間が読みやすい「文字列」に変換しなければなりません。その変換ルールを定義するのが、ピクチャ指定子です。
まずは、基本となる二つの文字の役割を整理しましょう。
- `9` (強制表示): 「ここには必ず数字が入るよ!」という指定です。値がゼロであっても、容赦なく `0` を表示します。
- `Z` (ゼロ抑制): 「ここがゼロなら、空白にしておいて!」という指定です。先頭の不要なゼロを消して、スッキリ見せるために使います。
具体的な挙動を見てみよう
百聞は一見にしかず。まずはコードで比較してみましょう。
/i
/ 数値編集の比較サンプル /
TEST_PROC: PROCEDURE OPTIONS(MAIN);
DCL VAL FIXED DEC(5) INIT(123);
/ 9を使った宣言:桁埋めが必要なコードやIDなどで重宝します /
DCL OUT_9 PIC ‘99999’;
/ Zを使った宣言:金額や数量など、読みやすくしたい時に必須です /
DCL OUT_Z PIC ‘ZZZZ9’;
OUT_9 = VAL; / 結果: ‘00123’ /
OUT_Z = VAL; / 結果: ‘ 123’ (先頭に空白が入る) /
PUT SKIP EDIT (‘9の出力:’, OUT_9) (A, A);
PUT SKIP EDIT (‘Zの出力:’, OUT_Z) (A, A);
END TEST_PROC;
ここがポイント!
- `99999` に `123` を入れると、足りない上の桁は `0` で埋められます。
- `ZZZZ9` に `123` を入れると、左側の `ZZ` は「ゼロだから隠す」という判断が働き、空白に置き換わります。最後の `9` は「たとえゼロでも最後の一桁は絶対表示して!」というガードの役割を果たしているんですね。
—
「え、マイナス値はどうなるの?」という疑問
現場でよくあるトラブルが、「負の数の扱い」です。
PL/Iのピクチャ指定子に `S` や `-` を追加すると、符号の制御ができるようになります。
/i
DCL VAL_NEG FIXED DEC(5) INIT(-123);
/ マイナス符号を付ける例 /
DCL OUT_NEG PIC ‘ZZZ9-‘;
OUT_NEG = VAL_NEG;
/ 結果は ‘ 123-‘ となります /
この「符号をどこに置くか」「ゼロの時にどう表示するか」という細かい仕様は、帳票レイアウトの要件と密接に関わります。マイグレーションの際、このピクチャ定義がズレていると「帳票の桁がズレた!」「マイナスが表示されない!」といった悲劇が起きがちです。
—
なぜPL/Iのピクチャは「奇妙」に見えるのか
COBOLエンジニアの方なら「COBOLも一緒でしょ?」と思われるかもしれません。しかし、PL/Iは「同じ変数に対して、数値として計算することも、文字列として編集することもできる」という非常に柔軟(時に危険)な性質を持っています。
例えば、ピクチャ指定した変数に対して加算を行うと、コンパイラは内部で「一度数値に変換して計算し、またピクチャ形式に戻す」という処理を自動で行います。この「隠れた変換コスト」こそが、PL/Iの奥深さであり、同時にパフォーマンスチューニングの勘所でもあります。
初学者の方へ:怖がらないで!
最初は記号の羅列に見えるかもしれませんが、「`9`は厳格な番人、`Z`は優しい空白メーカー」と覚えてみてください。
現場のソースコードを覗くときも、「なぜここは `9` なのか?」「なぜここは `Z` なのか?」を考えるだけで、当時のプログラマーが何を意図して帳票を作ったのか、その歴史が見えてくるはずです。
もし分からないことがあれば、いつでも聞いてくださいね。メインフレームの深淵は、意外と温かいですよ。
それでは、次回の記事でお会いしましょう!Happy Coding!
