COBOLの数値演算で桁あふれを防ぐ!初心者でもわかるサイズエラー対策
生徒
「先生、COBOLで数の計算をするときに“桁あふれ”って起きることがあるんですか?」
先生
「はい、起きます。たとえば、変数のサイズより大きな数を計算すると、エラーや正しくない結果になることがあるんです。」
生徒
「それって危険ですね……。どうやって防げばいいんでしょうか?」
先生
「いい質問ですね。今日は、COBOLで数値演算をするときに気をつける“桁あふれ(オーバーフロー)”と“サイズエラー”の回避方法を学びましょう。」
1. 桁あふれ(オーバーフロー)とは?
桁あふれ(けたあふれ)とは、計算結果が変数のサイズを超えてしまうことです。たとえば、99までしか入らない変数に100を入れようとした場合に起こります。
COBOLでは、変数の大きさはPIC(ピクチャ)句で決まります。たとえば、次のように定義します。
01 TOTAL-AMOUNT PIC 9(2) VALUE 99.
この場合、TOTAL-AMOUNTは2桁までの数字しか入れられません。もし100を代入しようとすると、値が入りきらず桁あふれになります。
2. SIZE ERRORとは?
SIZE ERRORとは、COBOLで演算をした結果が変数の定義サイズを超えたときに発生するエラーです。これは、コンピュータが「値が大きすぎて入らない!」という状態を検出したことを意味します。
たとえば、次のような例を見てみましょう。
IDENTIFICATION DIVISION.
PROGRAM-ID. SIZE-ERROR-SAMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 NUM-A PIC 9(2) VALUE 50.
01 NUM-B PIC 9(2) VALUE 60.
01 RESULT PIC 9(2).
PROCEDURE DIVISION.
ADD NUM-A TO NUM-B GIVING RESULT
ON SIZE ERROR
DISPLAY "サイズエラー発生!計算結果が大きすぎます。"
NOT ON SIZE ERROR
DISPLAY "計算結果:" RESULT
END-ADD.
STOP RUN.
サイズエラー発生!計算結果が大きすぎます。
この例では、50+60=110ですが、結果を入れるRESULTは2桁しかないため、SIZE ERRORが発生します。
ON SIZE ERROR句を使うことで、桁あふれが起きたときの処理を安全に制御できます。
3. 桁あふれを防ぐ3つのポイント
桁あふれを防ぐには、COBOLのデータ定義と演算方法に注意が必要です。ここでは3つの具体的な対策を紹介します。
① PIC句の桁数を余裕を持って設定する
計算で大きな数になる可能性がある場合は、変数の桁数を多めに設定しておきましょう。たとえば、2桁の数字を足し算するなら、結果を入れる変数は3桁にしておくと安全です。
01 NUM-A PIC 9(2) VALUE 50.
01 NUM-B PIC 9(2) VALUE 60.
01 RESULT PIC 9(3).
このように定義すると、50+60=110が問題なく入ります。システム開発では、将来的に数値が増える可能性を考えて、少し多めに桁を確保するのが一般的です。
② ON SIZE ERROR句で安全な処理を行う
演算命令(ADD、SUBTRACT、MULTIPLY、DIVIDEなど)には、ON SIZE ERRORをつけることで、エラー発生時の処理を明示的に書けます。
これにより、計算が失敗してもプログラムが止まることなく、安全にエラーメッセージを表示したり、代替の処理を実行したりできます。
③ NOT ON SIZE ERROR句を併用する
NOT ON SIZE ERRORを使えば、正常に計算できた場合の処理も明確に分けられます。これにより、エラーの有無に関係なく、正確な動作が保証されます。
4. さまざまな演算でのサイズエラー例
COBOLでは、加算(ADD)だけでなく、引き算(SUBTRACT)、掛け算(MULTIPLY)、割り算(DIVIDE)でもサイズエラーが起こります。ここではそれぞれの例を紹介します。
● SUBTRACT(引き算)での例
SUBTRACT 200 FROM 50 GIVING RESULT
ON SIZE ERROR DISPLAY "サイズエラー:結果がマイナスになりました。".
この場合、結果は「-150」になりますが、もしRESULTがPIC 9(3)(符号なし)だとマイナスを扱えないため、サイズエラーになります。
● MULTIPLY(掛け算)での例
MULTIPLY 99 BY 99 GIVING RESULT
ON SIZE ERROR DISPLAY "サイズエラー:掛け算の結果が大きすぎます。".
結果は9801になります。もしRESULTがPIC 9(3)だと4桁の数値を格納できず、サイズエラーになります。
● DIVIDE(割り算)での例
DIVIDE 100 BY 0 GIVING RESULT
ON SIZE ERROR DISPLAY "ゼロで割り算はできません!".
割り算で「0」で割るとエラーになります。COBOLはこのような危険な計算もON SIZE ERRORで防ぐことができます。
5. 実務で使える安全な数値演算の書き方
実際の業務システムでは、金額や数量などの数値を扱うとき、桁あふれを防ぐ工夫が欠かせません。以下は、安全な書き方の例です。
IDENTIFICATION DIVISION.
PROGRAM-ID. SAFE-MATH.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 PRICE PIC 9(6)V99 VALUE 999999.99.
01 TAX-RATE PIC 9V99 VALUE 1.10.
01 TOTAL PIC 9(7)V99 VALUE 0.
PROCEDURE DIVISION.
MULTIPLY PRICE BY TAX-RATE GIVING TOTAL
ON SIZE ERROR
DISPLAY "サイズエラー:金額が大きすぎます。"
NOT ON SIZE ERROR
DISPLAY "税込金額:" TOTAL
END-MULTIPLY.
STOP RUN.
税込金額:1099999.89
ここではVが小数点を表しています。桁数と小数点位置をしっかり設定することで、金額計算でも安全に処理できます。
また、ON SIZE ERRORを必ず書いておくことで、想定外の入力や桁あふれが起きたときにも安心です。
6. まとめ:エラーを恐れず安全に計算しよう
COBOLの数値演算では、「桁あふれ」と「サイズエラー」は避けられないテーマです。しかし、正しいデータ定義とON SIZE ERRORの活用で、トラブルを事前に防げます。
プログラミング初心者の方も、まずは「変数のサイズを大きめに」「サイズエラー処理を必ず書く」ことを意識しましょう。これだけで、より安全で信頼性の高いCOBOLプログラムを書くことができます。
まとめ
ここまで、COBOLにおける「桁あふれ」の仕組みと、その強力な対策法である「ON SIZE ERROR」について詳しく解説してきました。数値を扱うプログラムにおいて、計算結果が器(変数)の大きさを超えてしまう現象は、一見単純なミスに見えますが、基幹システムにおいてはデータの不整合やシステム停止を招く非常に重大なリスクとなります。特にCOBOLは銀行や公共機関といった「1円の狂いも許されない」現場で使われることが多いため、PIC句による厳密な型定義と、例外処理の実装は必須のスキルといえるでしょう。
数値演算を確実に制御するための重要ポイント
記事の内容を振り返ると、安全なコーディングのためには以下の3ステップが欠かせません。
- 精度の高いデータ設計: 計算結果が最大で何桁になるかを事前に予測し、PIC句で余裕を持った領域を確保すること。
- エラーハンドリングの徹底: すべての演算命令に「ON SIZE ERROR」を添え、万が一の事態に備えた代替処理を記述すること。
- 符号や小数点の意識: 負の数が発生する可能性があるなら「S」を、小数を扱うなら「V」を正しく使い分けること。
C#との比較で考える桁あふれの概念
現代的な言語であるC#などと比較すると、COBOLの桁管理がいかに独特であるかがわかります。例えばC#では、整数型(intやlong)の最大値を超えるとサイレントに値がループしてしまうことがありますが、checkedキーワードを使うことでCOBOLのサイズエラーに近い挙動を再現できます。
try
{
int maxVal = int.MaxValue;
// checkedブロック内で計算することで、オーバーフロー時に例外を発生させる
int result = checked(maxVal + 1);
Console.WriteLine(result);
}
catch (OverflowException ex)
{
Console.WriteLine("C#でもオーバーフロー検知!: " + ex.Message);
}
このように、言語が違えど「予期せぬ数値の爆発」を防ぐという思想は共通しています。COBOLの場合はこれを「言語の標準機能」として、より直感的に記述できるのが強みですね。
さらなるステップアップに向けて
サイズエラー対策をマスターしたら、次は「丸め処理(ROUNDED)」についても学習してみることをお勧めします。桁あふれを防ぐために桁数を制限すると、今度は端数の処理が問題になります。COBOLには、四捨五入を簡単に行うためのオプションも用意されています。
最後に、今回学んだ「ON SIZE ERROR」を組み込んだ、より実践に近いCOBOLのサンプルプログラムを掲載します。複数の演算を組み合わせた際の挙動を確認してみてください。
IDENTIFICATION DIVISION.
PROGRAM-ID. ADVANCED-CALC.
DATA DIVISION.
WORKING-STORAGE SECTION.
01 WS-UNIT-PRICE PIC 9(5) VALUE 15000.
01 WS-QUANTITY PIC 9(3) VALUE 10.
01 WS-DISCOUNT PIC 9(5) VALUE 5000.
01 WS-SUBTOTAL PIC 9(6).
01 WS-FINAL-TOTAL PIC 9(6).
PROCEDURE DIVISION.
* 掛け算による小計算出
MULTIPLY WS-UNIT-PRICE BY WS-QUANTITY GIVING WS-SUBTOTAL
ON SIZE ERROR
DISPLAY "エラー:小計が桁あふれしました。"
MOVE 0 TO WS-SUBTOTAL
NOT ON SIZE ERROR
DISPLAY "小計(単価×数量): " WS-SUBTOTAL
END-MULTIPLY.
* 引き算による最終金額算出
SUBTRACT WS-DISCOUNT FROM WS-SUBTOTAL GIVING WS-FINAL-TOTAL
ON SIZE ERROR
DISPLAY "エラー:最終金額の計算に失敗しました。"
NOT ON SIZE ERROR
DISPLAY "最終支払金額(割引後): " WS-FINAL-TOTAL
END-SUBTRACT.
STOP RUN.
小計(単価×数量): 150000
最終支払金額(割引後): 145000
プログラミングにおいて、最初から完璧なコードを書くのは難しいものです。しかし、エラーが起きる可能性を「あらかじめ想定しておく」だけで、そのプログラムの信頼性は飛躍的に向上します。COBOLの厳格さを味方につけて、堅牢なシステム開発を目指しましょう。
生徒
「先生、まとめを読んでさらによくわかりました!COBOLって、PIC句でガッチリとガードを固めているからこそ、サイズエラーが起きたときにすぐに気づけるんですね。」
先生
「その通りです。他の言語だと、エラーにならずに間違った数字のまま計算が続いてしまうこともあるけれど、COBOLは『おかしいぞ!』とはっきり教えてくれる。そこが信頼される理由なんです。」
生徒
「C#のサンプルコードも見て、オーバーフロー対策はどの言語でも大事なんだって実感しました。特に『ON SIZE ERROR』を書く癖をつけておけば、想定外の入力が来ても安心ですね。」
先生
「素晴らしい心がけです。業務システムでは、ユーザーがどんなに大きな数字を入力してくるかわかりません。プログラム側で常に防波堤を張っておくことが、プロのエンジニアへの第一歩ですよ。」
生徒
「はい!これからは変数の桁数に余裕を持たせて、しっかりとエラー処理を書いていこうと思います。次は四捨五入のROUNDEDについても教えてください!」
先生
「やる気満々ですね。いいでしょう、次回は端数処理のテクニックについて深掘りしていきましょう。まずは今回のサイズエラー対策を、自分のコードで試してみてくださいね。」