連載
» 2009年06月11日 00時00分 公開

COBOL - Getting Started(2):これであなたもCOBOLプログラマ (2/3)

[小林純一,マイクロフォーカス株式会社]

COBOLのデータ型

 プログラムで使用するメモリ上のデータ領域はデータ部に記述します。

 データ部は、宣言するデータのメモリクラスに応じて以下の節に振り分けられます。

 規格ではこのほかに帳票・画面の設計を記述する「REPORT SECTION」「SCREEN SECTION」があります。また、コンパイラによっては、このほかにスレッドローカルにアロケートされる「THREAD-LOCAL-STORAGE SECTION」、クラスのインスタンスに対して静的にアロケートされる「OBJECT-STORAGE SECTION」などを追加でサポートしています。

  節の見出しの構文 記述する内容
ファイル節 FILE SECTION. ファイルのレコードレイアウトなど
作業場所節 WORKING-STORAGE SECTION. 静的にアロケートされる領域(static)
局所場所節 LOCAL-STORAGE SECTION. 呼び出しスタック上にアロケートされる領域(auto)
連絡節 LINKAGE SECTION. 呼び出されるサブルーチン側の仮引数

 これらの節内に記述するデータ領域に名前を付けたものをCOBOLではデータ項目と呼びます。つまり変数のことです。データ項目は基本データ型を持つ基本項目と、1つ以上の基本項目が複合した構造を持つ集団項目とに分類されます。

 基本項目のデータ型を表現するにはPICTURE文字列と呼ばれる記法を使用します。以下にデータ型とそれを表現するPICTURE文字列の例を挙げます。

  PICTURE文字列 データ型の意味
1 PIC XXX 英数字3文字(3バイト)
2 PIC X(256) 英数字256文字(256バイト)
3 PIC 9(5) 数字5文字で十進5けたの符号なし整数を表す(5バイト)
4 PIC 999V99 数字5文字で十進整数部3けた、小数部2けたの符号なし数を表す(5バイト)
5 PIC 999PPP 数字3文字でその下に3けたの仮想的なゼロを補った数値を表す(3バイト)
6 PIC Z(7)9 8けたまでで先頭のゼロをサプレスした符号なし整数(8バイト)
7 PIC ZZZ9.9999 整数部4けた(ゼロサプレス)+小数点のピリオド+小数部4けた(9バイト)
8 PIC -----9 5けたまでの符号付整数をゼロサプレスしたうえで先頭に符号を付与する(6バイト)

 PICTURE文字列内のカッコで括られた数字は直前の文字がその数だけ繰り返されることを意味します。上記の1、2のように「9」を含まないPICTURE文字列は文字型の項目を表します。それ以外の「9」を含むものは数字型の項目です。

 数字型の項目のPICTURE文字列は項目内の文字の並び方とそれに対応して表現する数学的な値との関係を規定しているものです。例えば、3と4はどちらも5個の数字が並んだデータ形式ですが、その意味は異なっていて、3はゼロから99999までの整数を表すのに対し、4はゼロから999.99までを表しています。この規定は項目が算術演算などで使用される際にコンパイラによって解釈されます。

 なお、6、7、8は数字を表現してはいますが実際の項目中のバイト位置には数字ではない文字(空白、符号、小数点)が入ってきます。このようなものを数字編集項目と呼び、それ以外の数字項目と区別します。数字編集項目は主に帳票出力用途で使われるものであり、直接算術演算の中で使用することはできません。

 上に例示した数字表現はすべて十進1けたを1バイトの数字で表現しています。

 これに対し、バイナリや浮動小数点のデータ型も当然用意されています。これらを指定するのがUSAGE句です。以下にUSAGE句とその意味を示します。

USAGE BINARY 2の補数表現のバイナリ PICTURE句でけた数を指定
USAGE PACKED-DECIMAL 1バイトで十進2けたを表現する PICTURE句でけた数を指定
USAGE COMP-1 単精度浮動小数点 PICTURE句不要
USAGE COMP-2 倍精度浮動小数点 PICTURE句不要
USAGE COMP-3 PACKED-DECIMALと同義 PICTURE句でけた数を指定
USAGE COMP-4 BINARYと同義 PICTURE句でけた数を指定

 BINARYとPACKED-DECIMALに関しては、表現形式とは無関係に数値の扱いは十進であるところにCOBOLの特殊性があります。例えば、

PIC 9(5)V9(4) USAGE BINARY

で宣言された基本項目は、4バイトバイナリの形式になりますが、その中に格納される内容と、それが意味する数値との対応は以下のようになります(Big Endianの16進で表記してあります)。

00 00 00 01 0.0001(1/10000)
00 00 01 00 0.0256(2 **8/10000)
00 01 00 00 6.5536(2 **16/10000)
01 00 00 00 1677.7216(2 **24/10000)
3B 9A C9 FF 99999.9999

 この項目にはこれ以上の値を格納することは禁じられています。もし、FF FF FF FFという値がこの項目に格納されたらその場合の動作は規定されていません。

 特別にUSAGE COMP-5という書き方が用意されており、この場合は項目にアロケートされたバイトをフルに使用したバイナリ数値を許容します。すなわち、COMP-5項目はPICTUREで指定された十進けた数を超えた数値を表現することがあるのです。

 データ項目の宣言は、以下のように「レベル番号」を符番して項目名称、続いてPICTURE句、USAGE句などを記述し、末尾をピリオドで止めます。

01 ITEM-A PIC 9(5)V9(4) USAGE BINARY.

 レベル番号は、項目の階層構造を定義するために使用する1から49までの整数です。なぜかほとんどのCOBOLプログラマは上記のように「1」と書かずに「01」と2けたで書きますが、これは別に「1」でもかまいません。

 1が最上位の階層を表し、数字が増えるほど下位の階層を表します。同じレベル番号の項目が連続するときは、それらは同一階層となります。このようにして基本項目を構造化したものが集団項目です。以下に集団項目の定義例を示します。

01  従業員.
    05  従業員番号   PIC 9(7).
    05  従業員名     PIC X(30).
    05  入社年月日.
      10  入社年     PIC 9999.
      10  入社月     PIC 99.
      10  入社日     PIC 99.

 これは、JavaやC#でEmployeeというクラスを定義し、そこにEmpNumber、EmpName、HireDateといったメンバを追加するのに似ています。しかし、COBOLではこの集団項目「従業員」はそれに従属する基本項目が書かれた順番に隙間なく以下のように並んでいることが言語として規定されています。プログラマはこのことを前提としてコーディングすることができます。

COBOLコーディング例

 C言語の構造体のように自動的な語境界アラインメントはなされませんので、RISCマシンで他言語のプログラムを呼び出す場合は注意が必要です。

COBOLの算術演算

 上記で見たとおり、プログラマは数字項目に小数点上下の固定けた数を自由に与えることができます。COBOL2002規格ではコンパイラは小数点上下合計で31けたまでの宣言を許容しなければならないことになっています。コンパイラによっては、それ以上も許容しています。これは倍精度浮動小数点の十進精度が15けた程度であるのに比較するとかなりの高い精度です。

 実は、COBOLの1985年規格までは18けたまでを許容すればよいことになっていましたが、現代の金融業務の要請に伴い31けたまで拡張されたものです。

 これらの数字項目に対して二項演算子の+(加算)、-(減算)、*(乗算)、/(除算)、**(べき乗)と単項演算子の+、-(符号)を適用して算術式を書くことができます。演算子の優先度は以下の順序です。

1 単項の+ -
2 **(べき乗)
3 * /(乗除)
4 + -(加減)

 演算の結合規則は左から右となりますが、他言語と同様にカッコによる優先度の変更も可能です。Javaなどが提供しているモジュロ演算、シフト演算、論理演算はCOBOLにはありません。COBOL2002規格ではブーリアン型が導入されており、これらに対する論理演算はありますが、これを数字項目に適用することはできません。

 演算は十進で誤差なく実行され、結果は切り捨てで格納されます。実際にコンパイル・実行した以下の例を見ましょう。

COBOLコーディング例

 この

01 ITEM-1 PIC 9V999999 VALUE 1.

は、ITEM-1が整数部1けた、小数部6けたの数字項目であり、その初期値が1であることを示しています。

COMPUTE ITEM-1 = ITEM-1 / 3 * 3.

は、COMPUTE文を使用して算術式の結果を代入しています。このようにCOBOLでは実行文の先頭には必ず動詞が来なければならず、JavaやFORTRANのような代入式を書くことができません。ここでも英語の命令文を意識していることが分かります。

 さて、この算術式は「3で割る」と「3をかける」の2つの演算の複合式になっています。式の結合規則は左から右なので、これは

(ITEM-1 / 3) * 3.

と解釈され、まず1/3が計算されます。ここでCOBOLは、この結果をある長さの中間レジスタに切り捨てで格納しますので、0.3333333……という値となります。続いて、これを3倍しますので、結果は0.9999999……になり、これを切り捨てでITEM-1に格納するために、答えは0.999999になります。

 一方、切り捨てではなく四捨五入させたい場合には、以下のようにROUNDED指定を書きます。この場合、結果は1.000000になります。

COMPUTE ITEM-1 ROUNDED = ITEM-1 / 3 * 3.

 なお、COBOLには算術式を書く方法のほかにADD文、SUBTRACT文、MULTIPLY文、DIVIDE文が別途用意されており、それぞれ加減乗除の演算を英文と同じように書くことができます。参考までに上の例をこの書き方で書くと以下のようになります。

DIVIDE 3 INTO ITEM-1.
MULTIPLY 3 BY ITEM-1.

 除算の剰余は、DIVIDE文のREMAINDER句で取得することができます。

Copyright © ITmedia, Inc. All Rights Reserved.

RSSについて

アイティメディアIDについて

メールマガジン登録

@ITのメールマガジンは、 もちろん、すべて無料です。ぜひメールマガジンをご購読ください。