COBOLの数値演算で桁あふれを防ぐ!初心者でもわかるサイズエラー対策
生徒
「先生、COBOLで数の計算をするときに“桁あふれ”って起きることがあるんですか?」
先生
「はい、起きます。たとえば、変数のサイズより大きな数を計算すると、エラーや正しくない結果になることがあるんです。」
生徒
「それって危険ですね……。どうやって防げばいいんでしょうか?」
先生
「いい質問ですね。今日は、COBOLで数値演算をするときに気をつける“桁あふれ(オーバーフロー)”と“サイズエラー”の回避方法を学びましょう。」
1. 桁あふれ(オーバーフロー)とは?
桁あふれ(けたあふれ)とは、計算した結果が、あらかじめ用意していた変数の箱(器)のサイズを超えてしまい、入りきらなくなる現象のことです。専門用語ではオーバーフローとも呼ばれます。
身近な例で例えると、1リットルの牛乳パックに1.5リットルの牛乳を注ごうとするようなものです。入りきらなかった0.5リットルは溢れてしまい、正しい結果が得られなくなります。プログラミング未経験の方でも、「器のサイズには限界がある」と考えると分かりやすいでしょう。
COBOLでは、この変数の器の大きさをPIC(ピクチャ)句という命令で厳格に定義します。たとえば、次のように記述します。
01 TOTAL-AMOUNT PIC 9(2) VALUE 90.
01 ADD-VALUE PIC 9(2) VALUE 20.
01 RESULT-VAL PIC 9(2).
上記の例では、TOTAL-AMOUNT(合計金額)という変数は「9(2)」、つまり「数字2桁(0〜99)」までしか格納できない設計になっています。ここで、90に20を足す計算をしてみましょう。
ADD TOTAL-AMOUNT TO ADD-VALUE GIVING RESULT-VAL.
計算結果は「110」になりますが、受け取る側のRESULT-VALも2桁(最大99)しか入りません。このとき、100の位の「1」が溢れてしまい、変数の中身がおかしくなってしまうのが桁あふれの正体です。最悪の場合、システムが異常終了したり、誤った金額で計算が進行したりするため、金融機関などの基幹システムで使われるCOBOLにおいては非常に重要な注意点となります。
2. SIZE ERROR(桁あふれ)とは?初心者向けに分かりやすく解説
COBOLプログラミングにおいて、SIZE ERRORとは「計算結果が、あらかじめ用意していた変数の枠(桁数)を超えてしまった状態」を指します。一般的には「桁あふれ」とも呼ばれます。
例えば、最大で「99」までしか入らない箱に「100」を入れようとすると、数字が入りきらずに溢れてしまいますよね。コンピュータはこの状態を検知すると、計算結果が正しく格納できないためエラーとして扱います。これを放置すると、システムの計算結果がデタラメになってしまうため、非常に重要なチェック機能です。
プログラミング未経験の方でも分かりやすいように、具体的なプログラム例で見てみましょう。
IDENTIFICATION DIVISION.
PROGRAM-ID. SIZE-ERROR-SAMPLE.
DATA DIVISION.
WORKING-STORAGE SECTION.
* PIC 9(2)は「数字2桁(0〜99)」まで入る箱という意味です
01 NUM-A PIC 9(2) VALUE 50.
01 NUM-B PIC 9(2) VALUE 60.
01 RESULT PIC 9(2).
PROCEDURE DIVISION.
* 50 + 60 を計算して RESULT に入れようとします
ADD NUM-A TO NUM-B GIVING RESULT
ON SIZE ERROR
* 桁あふれが発生した時の処理
DISPLAY "エラー発生:計算結果が2桁(99)を超えました!"
NOT ON SIZE ERROR
* 正常に計算できた時の処理
DISPLAY "計算結果は " RESULT " です。"
END-ADD.
STOP RUN.
エラー発生:計算結果が2桁(99)を超えました!
このサンプルでは、50 + 60 = 110 となりますが、受け取り側の RESULT は PIC 9(2)(2桁)と定義されているため、100以上の数値は入りません。そこで 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についても教えてください!」
先生
「やる気満々ですね。いいでしょう、次回は端数処理のテクニックについて深掘りしていきましょう。まずは今回のサイズエラー対策を、自分のコードで試してみてくださいね。」