COBOL的问题转移到comp-3变量

时间:2010-07-01 20:48:48

标签: cobol

我在OpenVMS上运行的COBOL程序中遇到以下问题。

我有以下变量声明:

       01 STRUCT-1.
           02 FIELD-A       PIC S9(6) COMP-3.
           02 FIELD-B       PIC S9(8) COMP-3.

       01 STRUCT-2.
           03 SUB-STRUCT-1.
               05 FIELD-A   PIC 9(2).
               05 FIELD-B   PIC 9(4).
           03 SUB-STRUCT-2.
               05 FIELD-A   PIC 9(4).
               05 FIELD-B   PIC 9(2).
               05 FIELD-C   PIC 9(2).

以下代码:

      * 1st Test:     
           MOVE 112011   TO FIELD-A OF STRUCT-1
           MOVE 20100113 TO FIELD-B OF STRUCT-1

           DISPLAY "FIELD-A       : " FIELD-A OF STRUCT-1 CONVERSION
           DISPLAY "FIELD-B       : " FIELD-B OF STRUCT-1 CONVERSION

      * 2nd Test:
           MOVE 112011   TO SUB-STRUCT-1.
           MOVE 20100113 TO SUB-STRUCT-2.
           MOVE SUB-STRUCT-1 TO FIELD-A OF STRUCT-1
           MOVE SUB-STRUCT-2 TO FIELD-B OF STRUCT-1

           DISPLAY "SUB-STRUCT-1  : " SUB-STRUCT-1
           DISPLAY "SUB-STRUCT-2  : " SUB-STRUCT-2
           DISPLAY "FIELD-A       : " FIELD-A OF STRUCT-1 CONVERSION
           DISPLAY "FIELD-B       : " FIELD-B OF STRUCT-1 CONVERSION

哪个输出:

FIELD-A       :  112011
FIELD-B       :  20100113
SUB-STRUCT-1  : 112011
SUB-STRUCT-2  : 20100113
FIELD-A       :  131323
FIELD-B       :  23031303

为什么FIELD-AFIELD-B的值与第二次测试中的值不同?

我的程序中的其他移动DISPLAY移动到COMP-3变量,我没有这种行为。

2 个答案:

答案 0 :(得分:4)

在COBOL中,组级别数据是无类型的,无需强制转换即可移动。

元素级别数据始终具有关联的数据类型。类型化 转换数据以匹配类型 MOVE期间的接收元素。

在第一个实例中,您MOVE为压缩十进制字段的文字数值(112011),编译器将其转换为流程中的正确数据类型。正如您在任何编程语言中所期望的那样。

在第二个实例中,MOVE为组项的文字值。由于这是一个组项,编译器无法“知道”预期的数据类型,因此它始终将组移动作为字符数据(无数字转换)。当接收项具有与字符数据兼容的PICTURE子句时,这是正常的 - FIELD-AFIELD-BSUB-STRUCT-1的。存储为9并存储为PIC X时,PIC 9的内部表示没有区别。假设两者都是USAGE DISPLAY

现在,当您执行组级别从SUB-STRUCT-1移动到COMP-3(打包的十进制)时,您实际上会告诉编译器不要从DISPLAY转换为COMP-3格式。这就是你得到的。

尝试对您的代码进行以下修改。使用REDEFINES创建 移动的数字基本项。 COBOL会做适当的 移动基本数据时的数据转换。


       01 STRUCT-2.                  
           03 SUB-STRUCT-1.          
               05 FIELD-A   PIC 9(2).
               05 FIELD-B   PIC 9(4).
           03 SUB-STRUCT-1N REDEFINES
              SUB-STRUCT-1  PIC 9(6).
           03 SUB-STRUCT-2.          
               05 FIELD-A   PIC 9(4).
               05 FIELD-B   PIC 9(2).
               05 FIELD-C   PIC 9(2).
           03 SUB-STRUCT-2N REDEFINES
               SUB-STRUCT-2 PIC 9(8).

以下代码:


      * 3RD TEST:                                         
           MOVE 112011   TO SUB-STRUCT-1.                 
           MOVE 20100113 TO SUB-STRUCT-2.                 
           MOVE SUB-STRUCT-1N TO FIELD-A OF STRUCT-1      
           MOVE SUB-STRUCT-2N TO FIELD-B OF STRUCT-1      
           DISPLAY "SUB-STRUCT-1  : " SUB-STRUCT-1        
           DISPLAY "SUB-STRUCT-2  : " SUB-STRUCT-2        
           DISPLAY "FIELD-A       : " FIELD-A OF STRUCT-1 
           DISPLAY "FIELD-B       : " FIELD-B OF STRUCT-1 

注意:将字符数据移动到COMP-3字段可能会在引用接收项时给您带来可怕的SOC7数据异常异常终止。这是因为并非所有位模式都是有效的COMP-3数字。

答案 1 :(得分:2)

你有2个问题。

COBOL有几个数字数据结构。每个都有自己的一套规则。

对于PACKED DECIMAL(COMP-3)
•PIC子句的数字组件应始终加起来为ODD编号。 •小数点“V”确定小数点的位置。 •单个元素MOVE和数学函数将保持十进制值对齐 - 可以进行高级和低级截断 •为您处理数字数据类型转换(区域十进制到打包和二进制到打包)。

e.g。 S9(5)V9(2)COMP-3  包括2个小数位> 长度计算为ROUND UP [(7 + 1)/ 2] = 4字节

     S9(6)V9(2) COMP-3.                                            

包括2个小数位> 长度计算为ROUND UP [(8 + 1)/ 2] = 5个字节 但是第1个半字节是不可寻址的

COMP-3字段的最后1/2字节是符号的HEXIDECIMAL表示 符号½字节值为C =有符号正D =有符号负F =无符号(非COBOL)。

S9(6)V9(3)COMP-3值123.45。 长度计算为ROUND UP [(9 + 1)/ 2] = 5个字节
包含X'00 01 23 45 0C'
请注意小数对齐&零填充。


组级MOVE规则

COBOL数据字段结构定义为层次结构。

01 H-L组场 - &任何子组级别字段 -

  1. 几乎总是隐含的CHARACTER字符串值
  2. 如果单个元素字段是01或77级别 - 那么它可以是数字。
  3. 如果引用为Individual元素字段,则在组或子组级别下定义为数字的单个元素字段将被视为数字。
  4. 适用数字规则。 o正确的理由 o小数位对齐 o用零填充H-L(½字节) o数字数据类型转换
  5. MOVE或数学计算的接收字段确定是否会发生数字数据转换。

    数字数据转换 如果使用任何发送字段类型(组或元素)移动或执行数学计算到使用数字PIC子句定义的任何接收单个元素字段---则接收字段将进行数字数据转换。当非数字数据移动到接收数字定义字段或使用非数字数据尝试数学计算时,会发生S0C7异常终止。

    无数字数据转换 如果将任何字段类型(组或元素)移动到任何组或子组级别字段,则不会进行数字数据转换。
    •适用字符移动规则 •左对齐&垫有空格。

    这是数字定义字段中非数字数据的主要原因之一。

    包含数字元素字段的发送组级别MOVE的主要用途之一是包含数字元素字段(相同地映射)的接收组级别,用于使用1 MOVE指令重新初始化数字元素字段。

    清除掩码 - 或 - 数据传播MOVE也可用于表清除 - 其中表组级别大于255个字节。