这个字母数字到数字的移动有什么问题?

Tha*_*ess 3 cobol

当我将 a 中的数字移动PIC X到 a 时PIC 9,数字字段的值为 0。

FOO中,PIC X(400)具有“1”在余下的399移动第一字节和空格到PIC 9(02) BAR像这样

DISPLAY FOO
MOVE FOO to BAR
DISPLAY BAR
Run Code Online (Sandbox Code Playgroud)

产量

1
0
Run Code Online (Sandbox Code Playgroud)

为什么 BAR 是 0 而不是 1?[编辑:最初,'发生了什么?']

后记:NealB 说“不要编写依赖于晦涩的截断规则和/或数据类型强制的程序。在你所做的事情中要精确和明确。”

这让我意识到我真的想要COMPUTE BAR AS FUNCTION NUMVAL(FOO)包含在NUMERIC测试中,而不是MOVE.

Nea*_*alB 6

COBOL 中的数据移动是一个复杂的主题 - 但这里是您问题的简化答案。一些数据移动规则是直截了当的,符合人们的预期。其他的有些奇怪,可能会因编译器选项、供应商以及 COBOL 标准的版本而异(74、85、2002)。

考虑到上述情况,以下是对您的示例中发生的情况的解释。

当“大”的东西被移动到“小”的东西时,必须发生截断。这就是将 BAR 移至 FOO 时发生的情况。截断的发生方式由接收项目的数据类型决定。当接收项是字符数据(PIC X)时,最右边的字符将从发送字段中截断。对于数字数据,最左边的数字从发送字段中截断。这种行为几乎适用于所有 COBOL 编译器。

作为这些规则的结果:

  • 当以“1”开头的长“X”字段 (BAR) 后跟一串空格字符被移动到较短的“X”字段时,最左边的字符将被转移。这就是为什么在移动到另一个PIC X 项目时会保留“1”的原因。

  • 当长的“X”字段 (BAR) 被移动到“9”(数字)数据类型时,最右边的字符首先被移动。这就是为什么“1”丢失了,它从未移动过,BAR 中的最后两个空格是。

到目前为止已经足够简单了......接下来的有点复杂。究竟发生了什么是特定于供应商、版本、编译器选项和字符集的。对于本示例的其余部分,我将假设正在使用 EBCDIC 字符集和 IBM Enterprise COBOL 编译器。我还假设您的程序显示b 0 而不是 0 b

如果字段仅包含数字,则在 COBOL 中将PIC X数据移动到PIC 9字段是普遍合法的PIC X。大多数 COBOL 编译器PIC 9在确定其数值时只查看字段的低 4 位。一个例外是存储符号或缺少一个的最低有效数字。对于无符号数字,作为 MOVE 的结果,最低有效数字的高 4 位设置为 1(十六进制 F)(强制遵循不同的有符号字段规则)。低 4 位在没有强制的情况下被移动。那么,当一个空格字符移动到一个PIC 9场地?SPACE 的十六进制表示是“40”(ebcdic)。高 4 位“4”被翻转为“F”,低 4 位按原样移动。这导致最低有效数字 (lsd) 包含 'F0' 十六进制。这恰好是PIC 9数据项中数字“0”的无符号数字表示。其余的前导数字按原样移动(即“40”十六进制)。最终结果是 FOO 显示为 b 0。但是,如果您要执行“MOVE”或“DISPLAY” FOO 以外的任何操作,则剩余“数字”的高 4 位可能因此被强制为零。这会将它们的显示特性从空格翻转为零。

以下示例 COBOL 程序及其输出说明了这些要点。

   IDENTIFICATION DIVISION.
   PROGRAM-ID. EXAMPLE.
   DATA DIVISION.
   WORKING-STORAGE SECTION.
   01.
       05 BAR        PIC X(10).
       05 FOO        PIC 9(2).
       05 FOOX       PIC X(2).
   PROCEDURE DIVISION.
       MOVE '1         ' TO BAR
       MOVE BAR TO FOO
       MOVE BAR TO FOOX
       DISPLAY 'FOO : >' FOO '< Leftmost trunctaion + lsd coercion'
       DISPLAY 'FOOX: >' FOOX '< Righmost truncation'
       ADD ZERO TO FOO
       DISPLAY 'FOO : >' FOO '< full numeric coercion'
       GOBACK
       .
Run Code Online (Sandbox Code Playgroud)

输出:

FOO : > 0< Leftmost trunctaion, lsd coercion
FOOX: >1 < Righmost truncation
FOO : >00< full numeric coercion
Run Code Online (Sandbox Code Playgroud)

最后的话......最好不要对这种事情一无所知。不要编写依赖于模糊截断规则和/或数据类型强制的程序。对你正在做的事情要准确和明确。