🧩今日の学び
・PIC X(3)の入力は空白で埋められるため、見た目の値と実際の中身は異なる
・IS NUMERICは厳密すぎるため、現実の入力には合わないケースがあり、TEST-NUMVALで位置特定し判定するのが有効
・COBOLは値そのものではなく「中身の構造」で評価する言語である
係長)なんでそうなったかわかったか?バタフライエフェクト起きたんだろ?
なるお)ほんと性格悪いっすよね…
係)お前が言ったんだろうが!発言に責任持てよ(ニヤニヤ
な)その顔でニヤニヤしてたら、追い込みかけて楽しんでるヤバい人ですからね。
係)わるかったな…
な)えーと…、なんでってのがわからないけど、3桁用意したけど、1を入れたら、001が入っているわけっすよね?
それが数字に変換されたから、001になってるんじゃないんすか?
てか1を入れたら、なにか起きてたんすかね?
係)まず、3桁の数字入れてみろ。
な)へ? へい
IRERO 111 IRERO 222 IRERO 333 IRERO = 00666
え!?なにこれ!?計算されてますけど!?
係)それがヒントだぞ。
な)いや、HINT MORE!
…当然スルーっすね…、うーん、2桁だったらどうなるのこれ?
IRERO 11 ERROR ZANEN ENTER SUJI!! IRERO 22 ERROR ZANEN ENTER SUJI!! IRERO 33 ERROR ZANEN ENTER SUJI!! IRERO = 00000
あいやー。だめでやんの。
1桁と2桁が同じくだめなのに、3桁は行けるってことは、PIC X(3)が何か悪いことしてる、極悪人だってことすかね…。
係)そこまできたなら、説明していくぞ。
な)あ!極悪人代表の人!
係)なにぃ!?
な)いえ…お願いします…
PIC X(3)は空白で埋められている
係)01 Y PIC X(3). という「3文字分の箱」に「1」だけを入れてエンターを押すと、残りの2文字分を空にはできないので、勝手に 半角スペース が埋められているんだよ。
つまり、箱の中身は "1 " になってるというわけだ。
な)あー、余計なお世話君…
あ!ってことは001とか入れればいいってことっすよね!LET’S GO!
IRERO 001 IRERO 002 IRERO 003 IRERO = 00006
ぎゃー!!きたー!!
係)ほんとうるっさいな…
な)もうこの計算機にうっとりです。もう卒業式でいいです。「仰げば尊し」斉唱しちゃいましょうか!歌詞知らないっすけど。
係)まだ桁数不足が解決されてないだろ!なにが卒業だよ。幼稚園からやり直してこいよ。
な)そこまで!?
係)いいか、これは作った者にとっては、3桁で入力するってことがわかるが、それ以外の者にとっては、そんなことわからないだろ。
そこでだ、一つ関数を紹介するぞ。
IS NUMERICは厳しすぎる判定だった
まず、IF Y IS NUMERIC という条件式は「箱の端から端まで、1ミリの隙間もなく全部が数字か」という超スパルタな判定をするんでな、スペースを見つけた瞬間に「数字じゃない!」と弾いてしまう。
な)ほー
係)その次にあるFUNCTION NUMVAL(Y) という関数は、「スペースが混じってても無視して数字にしてくれる」んだ。
つまり、「IS NUMERIC のスパルタ判定から別の判定にできれば、1でも12でも普通に計算できる」わけだ。
それを可能にするのがTEST-NUMVALという関数だ。
な)ほー
係)つまり、わかるな?
な)はい、わかりません。
係)なんでだよ!
な)いやいやいやいや、何がわかるってんすか!?
係)だから、考えてみろって言ってんだよ!
な)むーん…、今がこうで、NUMVALさんは無理矢理にでも数字に変換してくれるんでしょ?
ELSE
IF Y IS NUMERIC
MOVE FUNCTION NUMVAL(Y) TO X
ADD X TO TOTAL
ELSE
ってことは、IS NUMERICで数字じゃない判定されて、ELSEに行っちゃたってことよね。
ってことは、IS NUMERICが犯人じゃないすか、犯沢さんじゃないすか。
係)だからIS NUMERICではなくて、TEST-NUMVAL使えっていう話だよ。
な)あ、そゆこと…
TEST-NUMVALにするってんだから…これでいいんすか?
IF Y = "="
CONTINUE
ELSE
IF FUNCTION TEST-NUMVAL(Y)
MOVE FUNCTION NUMVAL(Y) TO X
ADD X TO TOTAL
ELSE
係)これだと条件になってないだろ?
な)条件って、数字かどうかってこと?ってTEST-NUMVALが数字かどうかを表してくれるんじゃないんす?
係)TEST-NUMVALが数字かどうかってことを確認しないとならないだろ?
な)数字かどうかって…、だって数字じゃないんすか?
係)この関数TEST-NUMVALは「犯人の居場所」を突き止めてくれるんだよ。
な)犯人?係長じゃないんすか?
係)なんでだよ!犯沢さんとか言ってただろ!
いいか、FUNCTION TEST-NUMVAL(Y) という関数は、箱の中身を左から順番に調べていくんだよ。
な)左から?
係)そうだ。例えば、さっきお前が1を入力したら、数字入れろって怒られただろ?
それは”1■■“という文字が入ったからだ。■はスペースな。
お前がPIC X(3)と宣言したから、3桁の箱が出来上がったわけだが、一文字だけだったから、COBOLが気を利かせて足りない桁を補って、”1■■“となってしまったがために、NUMERICは「それは数字ではない」って判断をしたってわけだ。
な)ふみみ…
係)その証拠に、そのあと001を入力したら数字として認識されて計算されたろ?
な)あー
係)そのうえでもう一度さっきの話だ。
「FUNCTION TEST-NUMVAL (Y) は、引数Yを左端から評価していく関数だ。
したがって、「戻り値が 0 (エラーなし)であること」が、数字としての妥当性を担保する条件式になるわけだ」
な)むーん…
係)例えば、お前が01 Y PIC X(3). の箱にこんな入力をしたとして,
- 入力
"1"(これだと、1とスペース2つとなる)TEST-NUMVALの結果:0(スペースは無視できるからエラーなし!)
- 入力
"12A"(最後にAを入れた)TEST-NUMVALの結果:3(3文字目の『A』がおかしい!)
- 入力
"X55"(最初にXを入れた)TEST-NUMVALの結果:1(1文字目の『X』がおかしい!)
という意味合いになるので、IF FUNCTION TEST-NUMVAL (Y) = 0だと数字だから真として次に進んでよし!ってなるわけだ。
な)ほむむ。
係)わかったか?
な)なんとなく…
順番に見ていって、TEST-NUMVALが数字じゃない「とこ」を教えてくれるから、それを利用すれば、「(0だったから)数字」か「(0じゃなかったから)数字じゃない」かを判定できるってことっすか。
係)お、いいな!
そういった利用はExcelでもすることあるだろ?
な)あーそっすね。0で合計との計算ミス確認したりするアレっすね。
係)よし、つまりどうなる?
な)は?何の話?
係)コードだよ!
な)あ、いまコード書いてたんでしたっけ…。
つまり、Yを検査したら何もなかったから0であればいいってことだから、= 0でいいんじゃないっすか?
IF Y = "="
CONTINUE
ELSE
IF FUNCTION TEST-NUMVAL(Y) = 0
MOVE FUNCTION NUMVAL(Y) TO X
ADD X TO TOTAL
ELSE
係)よし全体整理して実行してみろ。
な)あい…
1IDENTIFICATION DIVISION. 2PROGRAM-ID. CALC-SUM. 3 4DATA DIVISION. 5WORKING-STORAGE SECTION. 6 701 X PIC 9(3) VALUE 0. 801 TOTAL PIC 9(5) VALUE 0. 901 Y PIC X(3). 10 11PROCEDURE DIVISION. 12 13PERFORM UNTIL Y = "=" 14 15 DISPLAY "IRERO" 16 ACCEPT Y 17 18 IF Y = "=" 19 CONTINUE 20 ELSE 21 IF FUNCTION TEST-NUMVAL(Y) = 0 22 MOVE FUNCTION NUMVAL(Y) TO X 23 ADD X TO TOTAL 24 ELSE 25 DISPLAY "ERROR ZANEN ENTER SUJI!!" 26 END-IF 27 END-IF 28 29END-PERFORM 30 31DISPLAY TOTAL. 32STOP RUN.
で、実行っと…で、1, 2, 3と入れていって=入れると…
みぎゃああああ!
IRERO 1 IRERO 2 IRERO 3 IRERO = 00006
か、か、係長!00006って出ちゃいました!!
係)だから当たり前だろ!!
な)ひぃ!ちゃんと動くなんて怖いー
係)何が怖いんだよ!
な)ここらで一杯コーラが怖い
係)…………ふざけんなよ。
な)ひっ!
係長のワンポイント
入力は見た目どおりの値じゃない。
箱の中身(スペース含む)で評価される。IS NUMERICは厳密すぎて、現実の入力には合わないこともある。
だからTEST-NUMVALで「どこまで正常か」を見て判断する。
COBOLは値ではなく、“中身の構造”を見て処理する言語だ。


コメント