【COBOL学習|豆知識】意外と知らない「REM」と「MOD」の落とし穴:負数計算の挙動をマスターする

導入:なぜ「REM」と「MOD」の使い分けが重要なのか

COBOLで数値計算を行う際、余りを求めるために「REM」関数や「MOD」関数を何気なく使っていませんか?実は、これらは似て非なるものです。特に負数(マイナスの値)が絡む処理において、この二つの関数は全く異なる結果を返します。この違いを理解していないと、日付計算や配列のインデックス計算で予期せぬバグを引き起こす原因になります。「計算が合わない」と悩む前に、両者の挙動を整理しておきましょう。

基礎知識:REMとMODの違い

まず、それぞれの定義を明確にします。
REM(Remainder)は、除算の「残余」を求める関数です。計算式は「被除数 – (商 × 除数)」となり、商は0に向かって切り捨てられます。そのため、結果の符号は「被除数(割られる数)」に依存します。
対してMOD(Modulo)は、数学的な「剰余」を求める関数です。結果の符号は常に「除数(割る数)」と同じになります。
プログラミングの世界では、特にカレンダー計算のように「常に正の値を循環させたい」場合には、数学的に整合性が取れるMODが適しています。

実装・解決策:負数入力時の挙動

例えば「-13 を 3 で割った余り」を考えたとき、REM関数では -1 となりますが、MOD関数では 2 となります。これは、MODが「-13 は 3 で割ると -5 回分で余り 2」という数学的サイクルを維持するためです。
現場で「0から2までのループを回したい」といった場合にREMを使用すると、負のインデックスが発生してシステムエラーになるリスクがあるため、ループやバッファリング処理にはMODを選択するのが定石です。

サンプルプログラム

以下のコードは、REMとMODの出力結果の違いをコンソールに出力するサンプルです。

IDENTIFICATION DIVISION.
PROGRAM-ID. MOD-VS-REM-TEST.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 NUM-A PIC S9(04) VALUE -13.
01 NUM-B PIC S9(04) VALUE 3.
01 RESULT-R PIC S9(04).
01 RESULT-M PIC S9(04).
PROCEDURE DIVISION.
> REM関数の実行(負数が残る)
COMPUTE RESULT-R = FUNCTION REM(NUM-A, NUM-B)
DISPLAY “REM(-13, 3)の結果: ” RESULT-R

> MOD関数の実行(数学的に正の剰余が返る)
COMPUTE RESULT-M = FUNCTION MOD(NUM-A, NUM-B)
DISPLAY “MOD(-13, 3)の結果: ” RESULT-M

GOBACK.

応用・注意点:現場でのバグ回避策

現場で最も注意すべきは、「入力値がマイナスになる可能性があるか」という点です。
例えば、ユーザーからの入力値や、減算によって求めた数値がマイナスに振れる可能性がある場合、安易にREMを使うと、配列の添字(サブスクリプト)として使用した際に「範囲外参照」エラーが発生します。
「負数になっても常に正のインデックスを取得したい」場合は、迷わずMODを使用してください。逆に、計算過程で符号を保持したまま余りを利用したい特殊な統計計算などの場合は、REMが適しています。関数の性質を理解し、要件に合わせて適切に使い分けることが、堅牢なプログラムへの第一歩です。

コメント

タイトルとURLをコピーしました