解码二进制编码的十进制

Decode a Binary Coded Decimal

我有一张外景照片 X(03),其中的日期为 X'160101',格式为 yymmdd。

我想知道如何将它转换为 pic x(06)。

到目前为止,我试图将它移回 9(03) comp 并将 9(03) 与 9(06) 比较,但没有用。

我该怎么做?

您拥有的是二进制编码的十进制 (BCD)。也就是说,数据保存在二进制字段中,但它是十进制表示,而不是二进制,这对值很重要。 X'160101' 为 1,442,049。 X'160201' 将为 1,442,305。因此,如果您能够将其视为二进制字段(您必须在二进制前添加一个二进制零以使其成为二进制字段的正确长度),您将不得不进行一些愚蠢的计算。

所以你做一些不同的事情,而且更容易。 BCD 不是原生 COBOL 数据类型。 PACKED-DECIMAL(通常与 COMP-3/COMPUTATIONAL-3 相同)是一种 BCD 类型,它在低位(最右边)半字节中包含一个符号值。所以不完全是 BCD,但您可以像这样将 BCD 视为 PACKED-DECIMAL:

01  BCD-TO-PACKED.
    05  BTP-SOURCE-BCD                  PIC XXX.
    05  BTP-PACKED-ZERO  PACKED-DECIMAL PIC 9 VALUE ZERO.
01  FILLER 
    REDEFINES BCD-TO-PACKED.
    05  BTP-PACKED-TO-MOVE
                         PAKCED-DECIMAL PIC 9(6)V9.

01  DATE-AS-PIC-X                       PIC X(6).
01  DATA-AS-CHARACTER-NUMERIC
    REDEFINES DATE-AS-PIC-X             PIC 9(6).


    MOVE your-source-value       TO BTP-SOURCE-BCD
    MOVE BTP-PACKED-TO-MOVE      TO DATA-AS-CHARACTER-NUMERIC

之后你就可以愉快地引用 DATE-AS-PIC-X 来做任何你想做的事了。

BCD-TO-PACKED 是一个四字节的组字段,通过 VALUE 子句并且没有任何变化,最后由 X'0F' 组成。这是一个无符号的压缩十进制字段,具有一位数字和零值。

然后为 BTP-SOURCE-BCD 执行 X-to-X MOVE。 BCD-TO-PACKED 现在看起来像这样:X'1601010F'。这对于压缩十进制字段是完全有效的。您可以将其除以 10 得到您的日期(将其重新定义为 PACKED-DECIMAL PIC 9(7)),但为什么要浪费 CPU?

相反,您在 REDEFINES 中定义一位小数 (V9)。当编译器生成代码以将其移动到另一个没有小数位的数字字段时,源小数位将被删除。急!除以 10 不除。

注意:选择的数据名称是为了帮助解释。您应该使您的名称对数据有意义,而不仅仅是使用 "trite" 个名称。 "Character numeric" 在 COBOL 中称为 USAGE DISPLAY,如果未提供 USAGE,则它是默认值。 USAGE 这个词本身很少使用。所以当 PIC X 或 PIC 9 字段没有其他用途时,USAGE DISPLAY 就是您所拥有的。

注意:您可能不应该使用两位数的年份。您将无法处理早于 2000 年或晚于 2199 年的日期。两位数年份的历史使用是由于昂贵的磁盘存储和 "data redundancy"(所有世纪值都是 19,所以为什么保留值 19同一个帐户有 80 次不同的时间)。如果使用两位数年份,请确保某处有与世纪相关的内容。

注意:如果您尝试将 PIC X 字段移动到数字字段,编译器将假定您在该字段中具有有效的字符编号,这是您最初尝试失败的原因之一。

如果你搜索Whosebug,你应该能找到答案(这个已经有人回答了)。

但是创建一个字段,如(my-date-x 保存日期):

   03  my-date-x            pic x(3).
   03  my-date-9            pic 9(6).

   03  date-ymdv0           pic 9(6)v9 comp-3.
   03  date-x               pic x(3) redefines date-ymdv0.

密码是

   Move 0                   to date-ymdv0 
   Move my-date-x           to date-x
   Move date-ymdv0          to my-date-9

它起作用的原因是 9(6)v9 comp3 160101 存储为 x'1601010c' 这就是你所拥有的(+ 0c 最后)。