COBOL 移动到 comp-3 变量时出现问题

发布于 2024-09-08 02:11:54 字数 1580 浏览 1 评论 0原文

我在 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 保存的值与我移入其中的值不同第二个测试?

我在程序中从 DISPLAYCOMP-3 变量有其他移动,但我没有得到这种行为。

I'm having the following problem in a COBOL program running on OpenVMS.

I have the following variable declaration:

       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).

And the following code:

      * 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

Which outputs:

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

Why FIELD-A and FIELD-B hold values different from what I move into them in the second test?

I've other moves from DISPLAY to COMP-3 variables in my program where I don't get this behavior.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

烟沫凡尘 2024-09-15 02:11:54

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

元素级数据始终具有关联的数据类型。打字的
数据被转换为匹配类型
MOVE 期间接收元件的位置。

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

在第二个实例中,您将文字值MOVE到组项目中。由于这是一个组项,编译器无法“知道”预期的数据类型,因此它始终将组移动作为字符数据(无数字转换)。当接收项具有与字符数据兼容的 PICTURE 子句时,这很好 - 其中 FIELD-AFIELD-B
SUB-STRUCT-1 是。当存储为 PIC X 和存储为 PIC 9 时,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 数字。

In COBOL, Group level data are typeless and are moved without casting.

Element level data always have an associated data type. Typed
data are cast to match the type
of the receiving element during a MOVE.

In the first instance you MOVE a literal numeric value (112011) to a packed decimal field and the compiler converts it to the correct data type in the process. Just as you would expect in any programming language.

In the second instance you MOVE a literal value to a group item. Since this is a group item the compiler cannot 'know' the intended data type so it always does group moves as character data (no numeric conversions). This is fine when the receiving item has a PICTURE clause that is compatible with character data - which FIELD-A and FIELD-B
of SUB-STRUCT-1 are. There is no difference in the internal representation of a 9 when stored as PIC X and when stored as PIC 9. Both are assumed USAGE DISPLAY.

Now when you do a group level move from SUB-STRUCT-1 to a COMP-3 (Packed Decimal) you effectively tell the compiler not to convert from DISPLAY to COMP-3 format. And that is what you get.

Try the following modifications to your code. Using REDEFINES creates
a numeric elementary item for the move. COBOL will do the appropriate
data conversions when moving elementary data.


       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).

And the following code:


      * 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 

Beware: Moving character data into a COMP-3 field may give you the dreaded SOC7 data exception abend when the receiving item is referenced. This is because not all bit patterns are valid COMP-3 numbers.

心房敞 2024-09-15 02:11:54

您有 2 个问题。

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

对于压缩十进制 ( COMP-3 )
• PIC 子句的数字部分加起来应始终为奇数。
• 小数点标记“V”决定小数点的位置。
• 各个元素的 MOVE 和数学函数将保持十进制值对齐 – 高位和低位截断都是可能的
• 为您处理数字数据类型转换(区域十进制到压缩以及二进制到压缩)。

例如S9(5)V9(2) COMP-3。
包括小数点后两位>
长度计算如下:ROUND UP[ (7 + 1) / 2] = 4 个字节,

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

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

-3 字段的最后 1/2 字节是符号的十六进制表示形式。
符号 1/2 字节值是 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 HL组赛场——&任何子组级别字段 –

  1. 几乎总是隐含的字符字符串值
  2. 如果单个元素字段是 01 或 77 级别 – 那么它可以是数字。
  3. 如果作为单个元素字段引用,则在组或子组级别下定义为数字的单个元素字段将被视为数字。
  4. 数字规则适用。
    o 右对齐
    o 小数点对齐
    o 用零填充 HL(½ 字节)
    o 数字数据类型转换

MOVE 或数学计算的接收字段决定是否会发生数字数据转换。

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

无数值数据转换
如果将任何字段类型(组或元素)移动到任何组或子组级别字段,则不会有数字数据转换。
• 角色移动规则适用。
• 左对齐和左对齐用空格填充。

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

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

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

You have 2 Issues.

COBOL has several Numeric Data Structures. Each has its own set of rules.

For PACKED DECIMAL ( COMP-3 )
• The numeric components of the PIC clause should ALWAYS add up to an ODD number.
• The decimal marker “V” determines the placement of the decimal point.
• The individual element MOVE and math functions will maintain the decimal value alignment – both high and low level truncation is possible
• Numeric data type conversion (zone decimal to packed & binary to packed) is handled for you.

e.g. S9(5)V9(2) COMP-3.
including the 2 decimal positions>
Length is calculated as ROUND UP[ (7 + 1) / 2] = 4 bytes

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

including the 2 decimal positions >
Length is calculated as ROUND UP[(8 + 1) / 2] = 5 bytes
But the 1st ½ byte is un-addressable

The last ½ byte of the COMP-3 fields is the HEXIDECIMAL representation of the sign.
The sign ½ byte values are C = signed positive D = signed negative F = unsigned (non COBOL).

S9(6)V9(3) COMP-3 VALUE 123.45.
Length is calculated as ROUND UP[(9 + 1) / 2] = 5 bytes
Contains X’00 01 23 45 0C’
Note the decimal alignment & zero padding.


Group Level MOVE rules

COBOL Data field structures are define as hierarchical structures.

The 01 H-L group field – & any sub-group level field –

  1. Is almost always an implied CHARACTER string value
  2. If an individual element field is a 01 or 77 level – then it can be numeric.
  3. Individual element fields defined as a numeric under a group or sub-group level will be treated as numeric if referenced as an Individual element field.
  4. Numeric rules apply.
    o Right justify
    o decimal place alignment
    o pad H-L (½ bytes) with zeros
    o Numeric data type conversion

The receiving field of a MOVE or math calculation determines if a numeric data conversion will occur.

Numeric Data Conversion
If you MOVE or perform a math calculation using any sending field type (group or element) to any receiving individual element field defined using a numeric PIC clause --- then numeric data conversion will occur for the receiving field. S0C7 abends occur when non-numeric data is MOVE ‘d to a receiving numerically defined field OR when math calculations are attempted using non-numeric data.

No Numeric Data Conversion
If you move any field type (group or element) to any group or sub-group level field then there will be NO numeric data conversion.
• Character MOVE rules apply.
• Left Justify & pad with spaces.

This is one of the primary causes of non-numeric data in a numerically defined field.

One of the primary uses of a sending group level MOVE containing numeric element fields to a receiving group level containing numeric element fields (mapped identically) is for re-initializing numeric element fields using 1 MOVE instruction.

A Clear Mask – or – a data propagation MOVE is also possible for table clears - where the table group level is greater than 255 bytes.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文