在COBOL中使用COMP的变量

Ash*_*shi 1 cobol mainframe

我试图了解具有COMP Usage子句的COBOL变量如何存储值.

我尝试了一个例子,如下所示

    01  VAR14          PIC S9(5) USAGE COMP.   

    MOVE 12345 TO VAR14
    DISPLAY VAR14
Run Code Online (Sandbox Code Playgroud)

在SPOOL中,价值VAR14即将到来0000012345. S9(5) COMP根据手册大小是4个字节,所以我的理解VAR14应该显示为000012345.二进制表示如下:

0000 0000 0000 0000 0011 0000 0011 0100?
Run Code Online (Sandbox Code Playgroud)

有人可以帮助理解产值0000012345吗?

谢谢

Bil*_*ger 9

在IBM的Enterprise COBOL中,有四种方法可以定义二进制字段:COMP; COMP-4; BINARY; COMP-5.

这是怎么发生的?COMPUTATIONAL字段(简称COMP,此处为"所有COMPUTATIONAL字段"的缩写)是"实现者定义的".这意味着在一个编译器中什么是COMP-something,在另一个编译器中可能是COMP-somethingelse,或者甚至可能没有直接的等价物.

是的,如果需要,您可以编写COMPUTATIONAL,COMPUTATIONAL-4和COMPUTATIONAL-5代码.编译器会很高兴.

为了标准化,1985 COBOL标准引入了BINARY和PACKED-DECIMAL作为用法.对于其他COBOL编译器的可移植性,这些将是COMP和COMP-3(压缩十进制)字段的最佳用法.

这些不同的二进制字段有什么区别?大部分都没有.COMP,COMP-4和BINARY实际上是编译器中彼此的同义词(更准确地说,COMP-4和BINARY是COMP的同义词).

COMP-5,也称为"原生二元",是不同的.COBOL有你称之为"十进制二进制"字段(COMP和兄弟姐妹).也就是说,数据存储为二进制,但其最大值和最小值是定义中使用的PICture子句的数量和完整值.

COMP PIC 9 - can contain zero to nine.
COMP PIC S99 - (signed) can contain -99 to +99.
COMP PIC 999 - can contain zero to 999.
Run Code Online (Sandbox Code Playgroud)

COMP-5是不同的.

COMP PIC 9 - can contain zero to 65535.
COMP PIC S99 - (signed) can contain -32768 to +32767.
COMP PIC 999 - can contain zero to 65535.
Run Code Online (Sandbox Code Playgroud)

COMP-5的作用是PICture用于定义字段的大小(与其他二进制字段一样),但每个可能的位值都有效.

PICture如何与定义的大小相关?PIC 9至PIC 9(4)将存储在半字大小的字段(两个字节)中.PIC 9(5)到PIC 9(9)将存储在字大小的字段(四个字节)中.PIC 9(10)到PIC 9(18)将存储在双字大小的字段(8个字节)中.

好的,那么这个差异如何(COMP-5使用所有位,COMP只能代表PICture的十进制值)会影响定义的内容?难道"原生二进制"听起来要比"非本地"所能提供的更好,而且明显更快吗?

不同之处在于它们如何截断.并且,由于闪烁为"原生二进制"声音,它通常比使用COMP&CO慢,因为截断.

COMP截断为PICture的十进制值.COMP-5截断到字段的大小.

考虑(仅用于演示的名称,仅使用描述性名称):

01  PROGA COMP PIC 9(4).
01  PROGB COMP-5 PIC 9(5).
01  PROGC BINARY PIC 9(4) VALUE 9999.

ADD PROGC TO PROGA
ADD PROGC TO PROGB
Run Code Online (Sandbox Code Playgroud)

记住PROGA的最大值为9999,并注意到19998很容易适应现有的字段大小,编译器可以实现添加,然后截断到十进制值,就地完成.

记住PROGB的最大值为65535,并且原始字段中有足够的空间来成功添加另外的65535,编译器必须生成一个原始大小加倍的临时字段,执行添加,以及然后截断回原始最大值,将结果返回到原始字段.

ADD 1 TO PROGA
ADD 1 TO PROGB
Run Code Online (Sandbox Code Playgroud)

请注意,使用这两个,ADD 1 TO PROGA,因为它小于9999,仍然允许ADD到位(显然),但ADD 1 TO PROGB 仍然需要扩展字段和所有那些捣乱因为PROGB中的值可能已经是65535,所以编译器必须允许这样做.

来参加展示.你有COMP PIC S9(5),你得到一个10位数的输出.为什么?好的,你已经计算出的大小,该字段长度为四个字节.但是,这应该会得到一个五位数的输出,范围在-99999到+99999之间.让我们假装你的领域是COMP-5 PIC S9(5).

对于COMP-5,所有位都有效,对于有符号字段,全字/字的范围是-2,147,483,648到+2,147,483,647.那是10位数,请注意.哪个匹配您输出中的10位数字.发生了什么?

编译器选项TRUNC.如果使用编译器选项TRUNC(BIN),则所有COMP/COMP-4/BINARY字段都将被视为COMP-5.故事结局.您有TRUNC(BIN)或由您,您的项目或您的站点默认选择.这不一定是个不错的选择.

编译器选项TRUNC的其他值是STD,它对COMP/COMP-4/BINARY执行"正常"截断,而OPT执行当时最佳(对于性能)的任何操作.

请注意,TRUNC(OPT)强制要求程序员签订合同."我不会,也绝不会,甚至永远不会考虑,允许COMP/COMP-4/BINARY字段的值不符合它的PICture.如果我这样做,那完全是我的错,全面,故事结束,没有哭我".

除了调查工作原理之外,不要只是改变TRUNC设置.如果你这样做,你可以破坏事物,这可能是一个非常非常微妙的突破.

我的建议:TRUNC(BIN),除非必须(有人决定,你别无选择),否则不要使用它; 如果您的网站害怕合同,TRUNC(STD)会使用; 如果您的网站对合同感到满意,则使用TRUNC(OPT).

在您需要的地方,使用COMP-5进行单独的字段定义.你需要在哪里?对于任何地方,您有一个二进制字段,其范围超出其PICture的"十进制值".例如,查看CICS COMMAREA的大小以及指示单个示例有多大的字段.查看COBOL程序中的VARCHAR主机字段.与JAVA或C/C++通信的数据可能就是这样.否则,对于新的节目,更喜欢BINARY,这表明你与1985年是最新的.

设置TRUNC用于调查目的.

       CBL TRUNC(STD)
       ID (or IDENTIFICATION) DIVISION.
Run Code Online (Sandbox Code Playgroud)

编译器选项也可以由JCL中的PARM语句设置以进行编译,但您可能无法访问它.CBL将覆盖PARM中设置的任何值.有一个安装选项可以防止使用CBL(也称为PROCESS).个别选项也可以在安装时"固定".如果您的网站已修复TRUNC或阻止了CBL,您将无法尝试这些内容.