皆さん、こんにちは!ベテランCOBOL技術者の〇〇です。今回は、COBOLの除算処理をより分かりやすく、そして安全に行うための「DIVIDE … END-DIVIDE」構文について、初心者の方にも分かりやすく解説していきます。
なぜDIVIDE END-DIVIDEが重要なのか?
COBOLで数値を計算する際、除算は避けて通れません。しかし、単純な除算だけでなく、割り切れない場合の「余り」をどう扱うか、あるいは「小数点以下の処理」をどうするかで、コードが複雑になりがちです。特に、複数の除算処理が連続する場合や、余りを使った後続処理がある場合、どこまでが一つの除算処理なのかが分かりにくくなり、バグの原因になることも。
「DIVIDE … END-DIVIDE」構文は、このような除算処理の区切りを明確にすることで、コードの可読性を高め、意図しないエラーを防ぐのに役立ちます。
DIVIDE END-DIVIDEの基礎知識
「DIVIDE … END-DIVIDE」は、COBOLにおける構造化制御構文の一つです。これは、除算命令の開始と終了を明示的に示すためのもので、特に以下のような場合に威力を発揮します。
- 剰余計算 (REMAINDER): 割り算を行った際に出る「余り」を専用の変数に格納したい場合。
- 端数処理: 除算結果の小数点以下の扱い(切り捨て、切り上げ、四捨五入など)を明確にしたい場合。
従来のCOBOLでは、単に `DIVIDE A INTO B.` のように記述することが一般的でしたが、これだけだと剰余や端数処理を同時に行う場合に、どこまでが除算の範囲なのかが分かりにくくなることがありました。`END-DIVIDE` を使うことで、除算処理のブロックが明確になり、コードの意図が伝わりやすくなります。
DIVIDE END-DIVIDEの実装方法
基本的な構文は以下のようになります。
DIVIDE A INTO B
[ROUNDED]
[REMAINDER C]
END-DIVIDE.
- A: 除数(割られる数)
- B: 被除数(割る数)
- ROUNDED: オプションで、結果を最も近い整数に丸める場合に使用します。(端数処理)
- REMAINDER C: オプションで、除算の余りを変数 `C` に格納します。
- END-DIVIDE: 除算処理の終了を明示します。
この構文を使うことで、除算処理とその結果の丸め、余りの取得を一つのまとまりとして記述できます。
サンプルプログラム
では、実際に「DIVIDE … END-DIVIDE」を使ったサンプルプログラムを見てみましょう。ここでは、ある金額を人数で割り、一人当たりの金額を計算し、さらに端数が出た場合にどうなるか、そして余り(端数)をどう扱うかを見ていきます。
IDENTIFICATION DIVISION.
PROGRAM-ID. DIVIDE-DEMO.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 TOTAL-AMOUNT PIC 9(7) VALUE 10000. > 合計金額
01 NUMBER-OF-PEOPLE PIC 9(3) VALUE 3. > 人数
01 AMOUNT-PER-PERSON PIC S9(7)V99. > 一人当たりの金額(小数点2桁)
01 REMAINDER-AMOUNT PIC 9(7). > 余りの金額
PROCEDURE DIVISION.
MAIN-LOGIC.
DISPLAY “合計金額: ” TOTAL-AMOUNT.
DISPLAY “人数: ” NUMBER-OF-PEOPLE.
> DIVIDE END-DIVIDE を使用した除算処理
DIVIDE TOTAL-AMOUNT INTO NUMBER-OF-PEOPLE
ROUNDED > 結果を四捨五入する
REMAINDER REMAINDER-AMOUNT > 余りを REMAINDER-AMOUNT に格納する
END-DIVIDE.
> 結果の表示
DISPLAY “一人当たりの金額(四捨五入): ” AMOUNT-PER-PERSON.
DISPLAY “余りの金額: ” REMAINDER-AMOUNT.
> ROUNDED を使用しない場合の比較
DIVIDE TOTAL-AMOUNT INTO NUMBER-OF-PEOPLE
REMAINDER REMAINDER-AMOUNT > 余りのみ取得
END-DIVIDE.
DISPLAY “一人当たりの金額(切り捨て): ” AMOUNT-PER-PERSON.
DISPLAY “余りの金額: ” REMAINDER-AMOUNT.
STOP RUN.
このプログラムでは、
1. `TOTAL-AMOUNT` (10000) を `NUMBER-OF-PEOPLE` (3) で割っています。
2. `ROUNDED` を指定しているので、一人当たりの金額 `AMOUNT-PER-PERSON` は `3333.33` に丸められます。
3. `REMAINDER REMAINDER-AMOUNT` を指定しているので、余り `1` は `REMAINDER-AMOUNT` に格納されます。
4. 次に `ROUNDED` を指定しない場合、`AMOUNT-PER-PERSON` は `3333.33` となり、余りは `1` となります。(COBOLのデフォルトの端数処理は切り捨てになりますが、`PIC`句で小数点以下を指定しているため、結果は小数点以下も考慮されます。ここでは `V99` を指定しているので、`3333.33` が格納されます。余りは `1` になります。)
5. `END-DIVIDE` で除算処理のブロックが終了していることが明確です。
応用と注意点
- 可読性の向上: `END-DIVIDE` を使うことで、除算処理の範囲が明確になり、コードを読む人が処理の流れを理解しやすくなります。特に、複雑な計算ロジックの中で除算が行われる場合に効果的です。
- エラー回避: 除算処理の区切りが曖昧だと、意図しない変数に余りが格納されたり、丸め処理が適用されなかったりする可能性があります。`DIVIDE … END-DIVIDE` を使うことで、このような間違いを防ぎやすくなります。
- `ROUNDED` と `REMAINDER` の併用: `ROUNDED` と `REMAINDER` は同時に指定できます。これにより、結果の丸めと余りの取得を一度の `DIVIDE` 文で行うことができます。
- `PIC`句の確認: 除算結果を格納する `AMOUNT-PER-PERSON` の `PIC`句は、小数点以下の桁数も考慮して適切に定義してください。今回の例では `S9(7)V99` としており、整数部7桁、小数点以下2桁を扱えるようにしています。
- ゼロ除算: 割る数 (`NUMBER-OF-PEOPLE` など) がゼロになる可能性がないか、事前にチェックする処理を忘れずに追加しましょう。ゼロ除算が発生すると、プログラムが異常終了してしまいます。
「DIVIDE … END-DIVIDE」構文は、地味ながらもコードの品質を向上させるための重要なテクニックです。ぜひ、皆さんのCOBOLプログラミングに取り入れてみてください!

コメント