
■ 乗算(掛け算)
取引先から貰ったデータを変換するプログラムがあるのですが、少しデータを弄る必要に迫られました。それ自体は大した修正ではないのですが、その中で変わった処理を使っていました。
IF IN-FGQT = "1"
THEN
MULTIPLY IN-QT BY -1 GIVING OUT-QTBLL
ELSE
MOVE IN-QT TO OUT-QTBLL
END-IF.
フラグの値で正負を逆転するだけの処理なのですが、それでMULTIPLYを使うんですか・・・
やっているのは、IN-QTに-1を掛けてOUT-QTBLLに突っ込んでいるだけ。これならMULTIPLY文を使わずにCOMPUTE文の方が良いと思うのだが・・・
ちょっと気になったので、MULTIPLY文の動作を実験してみました。
■ MULTIPLY文【書き方1】
COBOL文法書(NetCOBOL V10.0)によると、【書き方1】は「乗算の結果を乗数と置き換える」と書かれています。
構文はこうですね(エラー時の処理は省略)。
MULTIPLY {一意名-1 or 定数-1} BY {一意名-2}・・・ END-MULTIPLY
書き方1の規則を見ると「BYの前の作用対象に一意名-2を掛け、一意名-2に格納します。一意名-2の並びを書いた順に、この乗算を行います。」
言葉だけだと(並びを書いた順にの辺りが)良く分からなかったので、実際に動かしてみました。
プログラムはこんな感じ。
IDENTIFICATION DIVISION.
PROGRAM-ID. TEST100.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WK-AREA.
04 WK-NUM PIC 9(6) VALUE ZERO.
04 WK-NUM1 PIC 9(6) VALUE ZERO.
04 WK-NUM2 PIC 9(6) VALUE ZERO.
04 WK-NUM3 PIC 9(6) VALUE ZERO.
PROCEDURE DIVISION.
*
* 初期値を設定
COMPUTE WK-NUM = 10.
COMPUTE WK-NUM1 = 2.
COMPUTE WK-NUM2 = 3.
COMPUTE WK-NUM3 = 4.
*
* 初期値
DISPLAY "WK-NUM = " WK-NUM UPON CONSOLE.
DISPLAY "WK-NUM1 = " WK-NUM1 UPON CONSOLE.
DISPLAY "WK-NUM2 = " WK-NUM2 UPON CONSOLE.
DISPLAY "WK-NUM3 = " WK-NUM3 UPON CONSOLE.
*
* 掛け算
MULTIPLY WK-NUM BY WK-NUM1 WK-NUM2 WK-NUM3.
*
* 結果
DISPLAY "WK-NUM = " WK-NUM UPON CONSOLE.
DISPLAY "WK-NUM1 = " WK-NUM1 UPON CONSOLE.
DISPLAY "WK-NUM2 = " WK-NUM2 UPON CONSOLE.
DISPLAY "WK-NUM3 = " WK-NUM3 UPON CONSOLE.
*
EXIT PROGRAM.
コンソールへの出力結果です。
WK-NUM = 000010
WK-NUM1 = 000002
WK-NUM2 = 000003
WK-NUM3 = 000004
WK-NUM = 000010
WK-NUM1 = 000020
WK-NUM2 = 000030
WK-NUM3 = 000040
あ~、なるほど。BYの左側の値を、BYの右側の値に掛けて置き換えているのか。一定の掛け率で一気に計算する時に便利そう。
COMPUTE文に直すとこうなるのか。
COMPUTE WK-NUM1 = WK-NUM1 * WK-NUM.
COMPUTE WK-NUM2 = WK-NUM2 * WK-NUM.
COMPUTE WK-NUM3 = WK-NUM3 * WK-NUM.
COMPUTE WK-NUM4 = WK-NUM4 * WK-NUM.
■ MULTIPLY文【書き方2】
【書き方2】は「乗算の結果を乗数とは異なるデータ項目に格納する」だそうです。
構文はこうですね(エラー時の処理は省略)。
MULTIPLY {一意名-1 or 定数-1} BY {一意名-2 or 定数-2} GIVING 一意名-3 ・・・ END-MULTIPLY
書き方2の規則ですが「BYの前の作用対象にBYの後の作用対象を掛け、一意名-3に格納します。一意名-3の並びを書いた順に、この乗算の結果を格納します。」だそうです。
BYの前後の値を掛けて、GIVINGの右の項目(一意名-3)に設定するっていうのは分かるのですが、一意名-3が複数存在した時の動作が理解できません。掛け算の結果を複数の項目に一気に設定するって事なんでしょうか?
さっきのプログラムのMULTIPLYをちょっと変えてみます。
IDENTIFICATION DIVISION.
PROGRAM-ID. TEST100.
ENVIRONMENT DIVISION.
CONFIGURATION SECTION.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WK-AREA.
04 WK-NUM PIC 9(6) VALUE ZERO.
04 WK-NUM1 PIC 9(6) VALUE ZERO.
04 WK-NUM2 PIC 9(6) VALUE ZERO.
04 WK-NUM3 PIC 9(6) VALUE ZERO.
PROCEDURE DIVISION.
*
* 初期値を設定
COMPUTE WK-NUM = 10.
COMPUTE WK-NUM1 = 2.
COMPUTE WK-NUM2 = 3.
COMPUTE WK-NUM3 = 4.
*
* 初期値
DISPLAY "WK-NUM = " WK-NUM UPON CONSOLE.
DISPLAY "WK-NUM1 = " WK-NUM1 UPON CONSOLE.
DISPLAY "WK-NUM2 = " WK-NUM2 UPON CONSOLE.
DISPLAY "WK-NUM3 = " WK-NUM3 UPON CONSOLE.
*
* 掛け算
MULTIPLY WK-NUM BY WK-NUM1 GIVING WK-NUM2 WK-NUM3.
*
* 結果
DISPLAY "WK-NUM = " WK-NUM UPON CONSOLE.
DISPLAY "WK-NUM1 = " WK-NUM1 UPON CONSOLE.
DISPLAY "WK-NUM2 = " WK-NUM2 UPON CONSOLE.
DISPLAY "WK-NUM3 = " WK-NUM3 UPON CONSOLE.
*
EXIT PROGRAM.
んで、コンソールの出力結果です。
WK-NUM = 000010
WK-NUM1 = 000002
WK-NUM2 = 000003
WK-NUM3 = 000004
WK-NUM = 000010
WK-NUM1 = 000002
WK-NUM2 = 000020
WK-NUM3 = 000020
どうやら、予想通りのようです(なんだ、つまらん)。
同じく、COMPUTE文に直してみました。
COMPUTE WK-NUM3 = WK-NUM1 * WK-NUM.
COMPUTE WK-NUM4 = WK-NUM1 * WK-NUM.
うーん、複数の変数に同じ結果を書き込むって状況が理解出来ん。初期化なら集団項目にしてINITIALIZE文を発行すれば1行で済むし、それ以外って何があるだろう?
■ 後書き
COBOLの四則演算は、加算(足し算)はADD、減算(引き算)はSUBTRACT、除算(割り算)はDIVIDEっていう専用の処理(文)が用意されている訳ですが、私は敢えて使っていません。
実際の所、COMPUTE文で十分だし、後でプログラムを追う時も分かりやすいです。
それぞれに便利な機能がついているので、時には使いたくなるのですが、自分以外の人間がメンテナンスする事を考えると、無暗に使ってはならないと思うのです。
投稿記事の一覧:http://harikofu.web.fc2.com/
--- blog end —
スポンサードリンク


