COBOL中的数据移动是一个复杂的主题 - 但这里是 简化了您的问题的答案。一些数据移动规则 是直截了当的,并符合人们的期望。其他则有些bizzar,可能会因编译器选项,供应商以及COBOL标准版本(74,85,2002)中的不同而有所不同。
考虑到上述情况,下面是对您的示例中发生的事情的解释。
当某些'大'是 MOVEd到'小'截断必须发生。这是当BAR被移动到FOO时发生的情况。 如何发生截断取决于接收项目 数据类型。当接收项目是字符数据(PIC X)时,最右边的字符将从发送字段中截断。 对于数字数据,最左边的数字从发送字段中截断。对于所有COBOL 编译器来说,这种行为非常普遍。
由于这些规则consequense:
到目前为止很简单...下一个比较复杂。具体发生的是供应商,版本,编译器选项和字符集 。对于本例的其余部分,我将假设使用EBCDIC字符集和IBM Enterprise COBOL编译器。我 也假定您的程序显示
b
0而不是0
b
。
在COBOL中将PIC X
数据移动到PIC 9
字段中时,只要PIC X
字段仅包含数字,就是普遍合法的。大多数 COBOL编译器在确定其数值时仅查看PIC 9
字段的低4位。一个例外是至少有一个有效数字,其中存储了符号或缺少符号。对于无符号数字,最低有效数字 的高4位由于MOVE(强制遵循签名字段的不同规则)而被设置为1(十六进制F)。低4位是MOVEd,没有 强制。那么,当一个空格字符移动到PIC 9
字段时会发生什么? SPACE的十六进制 表示为'40'(ebcdic)。高4位'4'翻转为'F',低4位移动。这导致包含'F0'十六进制的 最低有效数字(lsd)。这恰好是PIC 9
数据项中数字“0”的无符号数字表示形式。 剩下的前几位数字按原样移动(即'40'十六进制)。最终结果是FOO显示为
b
0。但是,如果您要执行“移动”或“显示”FOO以外的其他任何操作,则剩余“数字”的高4位可能会被强制为0,作为 的结果。这将把它们的显示特性从空间转换为零。
以下示例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
.
输出:
FOO : > 0< Leftmost trunctaion, lsd coercion
FOOX: >1 < Righmost truncation
FOO : >00< full numeric coercion
最后的话......最好不要知道这种事情来什么。不要编写依赖于模糊规则和/或数据类型强制转换的程序。准确而明确地表达你在做什么。
您使用哪种COBOL和OS? –
您不可能在400字节的字段上使用NUMVAL。加上你的语法“AS FUNCTION”是不熟悉的。您不能将FOO定义/子定义/重新定义为小于或等于您可以拥有的最大数字位数(即18或31)的数值。请记住NUMVAL不喜欢非数字数据。 –