🧩今日の学び
・複合計算は一気に書くのではなく、順番に分解して一時変数で処理することで正しく実装できる
・Vは内部的な小数点であり、表示には関係しないため、見せ方は別途設計する必要がある
・COBOLは「計算・保持・表示」を分けて考える言語である
なるお)四則演算だけでなんか大変でしたね…、ここからもっとなんすよね…?
係長)まぁ、そうだが、最後に全部混ぜ込んだ複合計算してみろ。
な)え…
係)そうだな…
1 + 2 - 3 ✕ 4 ÷ 5
でいくか。小数点があれば第一位までだ。
な)えええ!
係)なんかいい反応するようになったな。
な)ううう。
係)まず流れを説明してみろ。
な)いきなり始めるんすね…カステラ食べません?下のザラメ食べません?
係)ザラメなら食いながらでもできるだろ!
な)いやでも、ザラメが本体ゆえに、それを味わわない人生なんて、生きる意味がないわけで。
係)いいからやる!
な)…あい…
複合計算は「順番に分解する」
な)えっと、まず3 X 4 をしてから5で割るんよね。もうここで、小数点以下になるじゃない。
それに1+2から引くだよね。
ってことはこうっすよね?
① 3 × 4 = 12 ② 12 ÷ 5 = 2.4 ③ 1 + 2 = 3 ④ 3 - 2.4 = 0.6
係)そうだな。
であれば、どう準備していく?
な)まずは、A〜Eの変数作って、それぞれに値を入れる1, 2, 3, 4, 5入れる。
そして、計算用の変数も作る…一つ、いや、二つかな。
(前半部分の計算結果)-(後半部分の計算結果)
というのが最終で行くのが分かりやすいよね。
係)いいな。
であれば、PROCEDURE DIVISIONの前まで整えてみろ。
な)あい。いつものやつだから…
IDENTIFICATION DIVISION. PROGRAM-ID. COMPLEX-TEST. DATA DIVISION. WORKING-STORAGE SECTION. 01 A PIC 9(3)......
COBOLの小数は「V」で管理する
な)係長もっかい、小数教えてほしいです…
係)こうだ。
01 A PIC 9(3)V9(1). 9(3) → 整数3桁 V → 小数点 9(1) → 小数1桁
説明はあとにして、続けてみろ。
な)あい…。
IDENTIFICATION DIVISION. PROGRAM-ID. COMPLEX-TEST. DATA DIVISION. WORKING-STORAGE SECTION. 01 A PIC 9(3)V9(1) VALUE 1. 01 B PIC 9(3)V9(1) VALUE 2. 01 C PIC 9(3)V9(1) VALUE 3. 01 D PIC 9(3)V9(1) VALUE 4. 01 E PIC 9(3)V9(1) VALUE 5. 01 TEMP PIC 9(3)V9(1). 01 RESULT PIC 9(3)V9(1).
な)ってんで、どうでやんしょ。
係)ま、いいだろう。
それじゃ計算部分だな。一つ一つ分解してやっていけ。
な)あい
計算は「一時変数」で分ける
な)えーと、①から④の式を落とし込んでいこうかな。
MOVE C TO TEMP.
MULTIPLY D BY TEMP.
DIVIDE E INTO TEMP.
というのが一つで、区切りで、
MOVE A TO RESULT.
ADD B TO RESULT.
SUBTRACT TEMP FROM RESULT
となって結果がでると…
係)全体はどうなる?
な)あっはい。
IDENTIFICATION DIVISION.
PROGRAM-ID. COMPLEX-TEST.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 A PIC 9(3)V9(1) VALUE 1.
01 B PIC 9(3)V9(1) VALUE 2.
01 C PIC 9(3)V9(1) VALUE 3.
01 D PIC 9(3)V9(1) VALUE 4.
01 E PIC 9(3)V9(1) VALUE 5.
01 TEMP PIC 9(3)V9(1).
01 RESULT PIC 9(3)V9(1).
PROCEDURE DIVISION.
MOVE C TO TEMP.
MULTIPLY D BY TEMP.
DIVIDE E INTO TEMP.
MOVE A TO RESULT.
ADD B TO RESULT.
SUBTRACT TEMP FROM RESULT.
DISPLAY RESULT.
STOP RUN.
えと、実行しますね?
000.6
あ、出た。
係)よしOKだな。
な)さっき、説明がーとか言ってましたが、なんなんす?
表示は別物:ZZZ.9で整える
係)今ターミナルに000.6って普通に小数点が表示されてるだろ?
な)ええ。
係)今使っているコンパイラ(GnuCOBOL)だと気を利かせて表示してくれたが、一般的なCOBOLの環境だとそうはいかないんだ。
な)ほへ?
係)V はあくまで「内部的な小数点の位置」を示すだけの目印にすぎない。
だから、そのまま DISPLAY しても点は表示されず、環境によっては000や006、0006みたいに数字の羅列が出ることも普通にある。
な)え、でも、点がないと、0.6なのか6なのか分かんないじゃないすか。こんな横暴が許されるなんて…
係)別に横暴じゃないからな!それぞれの仕様ってだけだからな!
だからこそ、人間に正しく見せるための「表示用の変数(PIC ZZZ.9)」をちゃんと作っておくのが大事なんだ。
な)表示用っすか?
係)つまり、「今たまたまそのまま表示できたからといって、どんな環境でも表示されると思ってはだめだ」ってことだ。
そのため、画面に出す直前に ZZZ.9 という書き方をして形を整えるぞ。
01 DISP PIC ZZZ.9. MOVE RESULT TO DISP. DISPLAY DISP.
ZZZ.9の意味はこうだ。
Z 「もし先頭の数字が0なら、空白(スペース)にして消せ」という指示。
. 「ここに実際の小数点を表示しろ」という指示。
9 「数字が0でも、絶対にそのまま表示しろ」という指示。
RESULTは「計算用」、DISPは「見せる用」という分け方だ。ZZZ.9を入れて計算してみろ?
な)あーい。これに修正して実行っと…
IDENTIFICATION DIVISION.
PROGRAM-ID. COMPLEX-TEST.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 A PIC 9(3)V9(1) VALUE 1.
01 B PIC 9(3)V9(1) VALUE 2.
01 C PIC 9(3)V9(1) VALUE 3.
01 D PIC 9(3)V9(1) VALUE 4.
01 E PIC 9(3)V9(1) VALUE 5.
01 TEMP PIC 9(3)V9(1).
01 RESULT PIC 9(3)V9(1).
01 DISP PIC ZZZ.9.
PROCEDURE DIVISION.
MOVE C TO TEMP.
MULTIPLY D BY TEMP.
DIVIDE E INTO TEMP.
MOVE A TO RESULT.
ADD B TO RESULT.
SUBTRACT TEMP FROM RESULT.
MOVE RESULT TO DISP.
DISPLAY RESULT.
DISPLAY DISP.
STOP RUN.
000.6 .6
あ、0消えた。ほーほー。
あれ?ってことは、ZZ9.9にすると…
000.6 0.6
0.6のほうが良さげじゃないっすか?
係)いい考え方だ。
画面に「000.6」や「 .6」って出たらカッコ悪いしな。 見やすい形に整形するのも大事だぞ。
おむすび
な)くほー。スタイリッシュな見た目に整える。まさにキングオブスタイリッシュな俺だからこそ、この考えに至ったわけっすね!
係)じー…
な)な、なんす!?
係)いや、スタイリッシュの意味が違う世界ってあるんだなと。
な)ええ!?
係長のワンポイント
COBOLは計算だけすれば終わりじゃない。
計算・保持・表示をすべて分けて考える言語だ。Vは内部の小数点であって、表示されるものじゃない。
だからそのままDISPLAYしても、環境によって見え方が変わる。
正しく計算するだけでなく、正しく“見せる”までが処理だ。


コメント