技術とか戦略とか

IT技術者が技術や戦略について書くブログです。

COBOL:S9項目の文字コード

COBOLの符号付きの数字項目について、文字コード(バイナリ)だとどのように値を保持しているのかの解説が英語しかなかったので、記事を書きます。
 
符号付きの数字項目は「PIC S9(03)」のように定義するのですが、符号を示す「S」が付いたからといってバイト数が増えることはありません。
では、どのようにして符号の情報を保持しているのでしょうか。
 
英語では以下の文献があります。
 
EBCDIC to ASCII Conversion of IBM Signed Fields (Zoned, Over-punched Fields) - A Disc Interchange technical article

http://www.3480-3590-data-conversion.com/article-signed-fields.html

 
メインフレーム(ホストコンピュータ)の世界で良く使われる文字コードとしてEBCDICという文字コードがあるのですが、EBCDICでは以下のように値を保持します。

 

バイナリ 実際の値
F0 0
F1 1
F2 2
F3 3
F4 4
F5 5
F6 6
F7 7
F8 8
F9 9

 
符号無しの数値項目の場合は、これを単純に並べるだけです。
例えば、「120」は、「F1 F2 F0」のように値を保持します。
 
符号有りの数値項目の場合は、最後の桁について、上位4ビットを変更することで符号を表現します。
「+」を表現する時は「F」の箇所が「C」になりますし、「-」を表現する時は「F」の箇所が「D」になります。
例えば、「+120」は「F1 F2 C0」になりますし、「-120」は「F1 F2 D0」になります。
(ただし、「+」の場合は、「C」にせずに「F」のままセットされることも多いです。「C」にならなかったとしても慌てないでください。)
 
ちなみに、ここまでの話はゾーン10進数の話です。
パック10進数については既に記事を書いていますので、以下の記事を参照して下さい。
 
COBOLにおけるパック10進数(COMP-3)のデータの持ち方 - 技術とか戦略とか

https://akira2kun.hatenablog.com/entry/2018/10/01/014401

 
-------------------------------
 
以下、opensource COBOL で試してみた結果です。
opensource COBOL ではASCIIコードで出力され、ASCIIコードの場合の符号無し数値項目(ゾーン10進数)は上位4ビットが「3」になるのですが、「-」の場合は上位4ビットが「7」になるようです。「+」の場合は符号無し数値項目の場合と変わりませんでした。
なお、パック10進数の場合はEBCDICの場合と値の持ち方は同じです。
 
【テストコード】
       IDENTIFICATION    DIVISION.
       PROGRAM-ID.       SIGNTEST.
       ENVIRONMENT       DIVISION.
       INPUT-OUTPUT      SECTION.
       FILE-CONTROL.   
           SELECT  F1  ASSIGN  TO  "C:\tmp\a.txt".
      *
       DATA                  DIVISION.
       FILE                  SECTION.
       FD  F1.
       01  F1R.
           03  F1-REC        PIC X(52).
      *
       WORKING-STORAGE       SECTION.
       01  F1-REC-WORK.
           03  F1-REC1       PIC 9(10) VALUE 1234567890.
           03  KAIGYO1       PIC X(02) VALUE X"0D0A".
           03  F1-REC2       PIC S9(10) VALUE +1234567890.
           03  KAIGYO2       PIC X(02) VALUE X"0D0A".
           03  F1-REC3       PIC S9(10) VALUE -1234567890.
           03  KAIGYO3       PIC X(02) VALUE X"0D0A".
           03  F1-REC4       PIC S9(10) COMP-3 VALUE +1234567890.
           03  KAIGYO4       PIC X(02) VALUE X"0D0A".
           03  F1-REC5       PIC S9(10) COMP-3 VALUE -1234567890.
           03  KAIGYO5       PIC X(02) VALUE X"0D0A".
      *
       PROCEDURE         DIVISION.
      *
      * 各種処理の呼び出し
      *
       000-CONTROLLER-S.
           PERFORM  100-START-S THRU 100-START-E.
           PERFORM  200-MAIN-S  THRU 200-MAIN-E.
           PERFORM  300-END-S   THRU 300-END-E.
           STOP RUN.
       000-CONTROLLER-E.
      *
      * 前処理
      *
       100-START-S.
           OPEN  OUTPUT F1.
       100-START-E.
      *
      * 主処理
      *
       200-MAIN-S.
           MOVE F1-REC-WORK TO F1-REC.
           WRITE F1R.
       200-MAIN-E.
      *
      * 後処理
      *
       300-END-S.
           CLOSE  F1.
       300-END-E.
 
【実行結果】

f:id:akira2kun:20190625223325j:plain