COBOL中带有用法COMP的变量

COBOL中带有用法COMP的变量,cobol,mainframe,Cobol,Mainframe,我试图理解COBOL变量与COMP USERATION子句如何存储值 我尝试了下面的一个例子 01 VAR14 PIC S9(5) USAGE COMP. MOVE 12345 TO VAR14 DISPLAY VAR14 在SPOOL中,VAR14的值为0000012345。 S9(5)COMP大小根据手册为4字节,因此我的理解是VAR14应显示为00001245。 二进制表示形式如下所示: 0000 0000 0000 0000 0011

我试图理解COBOL变量与COMP USERATION子句如何存储值

我尝试了下面的一个例子

    01  VAR14          PIC S9(5) USAGE COMP.   

    MOVE 12345 TO VAR14
    DISPLAY VAR14
在SPOOL中,
VAR14
的值为
0000012345
S9(5)COMP
大小根据手册为4字节,因此我的理解是
VAR14
应显示为
00001245
。 二进制表示形式如下所示:

0000 0000 0000 0000 0011 0000 0011 0100‬
有人能帮助理解输出值
0000012345


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

这是怎么发生的?计算字段(COMP简称COMP,这里简称“所有计算字段”)是“实现者定义”。这意味着一个编译器中的COMP-somethingelse可能是另一个编译器中的COMP-somethingelse,甚至可能没有直接等价物

是的,如果你想的话,你可以编写计算,计算-4和计算-5。编译器会很高兴的

为了使事物标准化,1985年的COBOL标准引入了二进制和压缩十进制作为用法。为了便于移植到其他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.
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.
COMP-5的情况是,图片用于定义字段的大小(与其他二进制字段一样),但每个可能的位值都是有效的

图片与定义的大小有什么关系?PIC 9至PIC 9(4)将存储在一个半字大小的字段中(两个字节)。PIC 9(5)到PIC 9(9)将存储在一个字大小的字段中(四个字节)。PIC 9(10)至PIC 9(18)将存储在一个双字大小的字段(八个字节)中

好的,那么这个差异(COMP-5使用所有的位,COMP只能表示图片的十进制值)是如何影响定义的呢?“本机二进制”听起来不是比任何“非本机”都好,而且显然更快吗

区别在于它们如何截断。而且,由于截断的原因,它和“本机二进制”声音一样闪烁,通常比使用COMP&CO慢

COMP截断为图片的十进制值。COMP-5截断为字段的大小

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

请记住PROGA的最大值为9999,并注意19998很容易适应字段的现有大小,编译器可以执行加法,然后将其截断为十进制值,所有这些都在原位

请记住,PROGB的最大值为65535,并且原始字段中有足够空间再成功添加65535的可能性非常小,编译器必须生成一个临时字段,其大小为原始大小的两倍,进行添加,然后截断回原始最大值,将结果返回到原始字段

ADD 1 TO PROGA
ADD 1 TO PROGB
请注意,使用这两个函数,将1添加到PROGA,因为它小于9999,仍然允许在适当的位置进行添加(显然),但是将1添加到PROGB仍然需要扩展字段和所有这些操作,因为PROGB中可能已经有65535的值,所以编译器必须考虑到这一点

来展览。你有COMP PIC S9(5),你得到一个10位数的输出。为什么?好的,您计算出的大小,字段是四个字节长。但是,这应该会得到一个5位数的输出,范围在-99999到+99999之间。让我们暂时假设您的字段是COMP-5 PIC S9(5)

对于COMP-5,所有位都是有效的,对于有符号字段,完整字/字的范围是-2147483648到+2147483647。注意,这是10位数字。与输出中的10位数字相匹配。发生了什么事

编译器选项TRUNC。如果使用编译器选项TRUNC(BIN),则所有COMP/COMP-4/二进制字段都将被视为COMP-5。故事结束了。您拥有由您、您的项目特别选择的TRUNC(BIN),或者作为您的站点默认值。这不一定是一个好的选择

编译器选项TRUNC的其他值是STD,它对COMP/COMP-4/BINARY执行“正常”截断,OPT则执行当时最好的(性能)操作

请注意,TRUNC(OPT)对程序员强加了一个契约。“我不会,绝不会,甚至不会考虑,允许一个COMP/COMP-4/二进制字段有一个不符合它的图片的值。如果我这样做,这都是我的错,完全停止,故事结束,并且没有从我哭”。 除非是为了调查事情是如何工作的,否则不要只是设置和更改TRUNC设置。如果你这样做,你可以打破一些东西,这可能是一个非常非常微妙的突破

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

在需要的地方,对于单个字段定义,请使用COMP-5。你需要去哪里?对于任何位置,都有一个二进制字段,其范围超出其图片的“十进制值”。例如,查看CICS COMMAREA的大小和指示单个示例有多大的字段。查看COBOL程序中的VARCHAR主机字段。与JAVA或C/C++通信的数据可能就是这样。否则,对于新程序,首选二进制,这表明
ADD 1 TO PROGA
ADD 1 TO PROGB
       CBL TRUNC(STD)
       ID (or IDENTIFICATION) DIVISION.
Picture           Number of Bytes
S9 to S9(4)       2
S9(5) to S9(9)    4
S9(9) to S9(18)   8