当我将 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
.
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)
最后的话......最好不要对这种事情一无所知。不要编写依赖于模糊截断规则和/或数据类型强制的程序。对你正在做的事情要准确和明确。