COBOL DATATYPE CONVERSION:将DDMMYY中的日期转换为3字节的压缩十进制数

时间:2016-02-05 12:22:00

标签: type-conversion cobol packed-decimal

我有一个要求,我想将数字格式的日期(DDMMYY)移动到3字节的压缩十进制/ comp-3。 必须将日期移动到仅为其分配3个字符/字节的文件中。 这就是我的尝试。

 03  WD-DDMMYY-DT-NUMERIC         PIC 9(06).      
 03  WD-DDMMYY-DT-COMP3           PIC S9(06) COMP-3.
 03  WD-DDMMYY-REDF  REDEFINES WD-DDMMYY-DT-COMP3.
     05  WD-3CHARS-DT-COMP3       PIC X(03).      
     05  FILLER                   PIC X(01).    


Move WD-DDMMYY-DT-NUMERIC         to  WD-DDMMYY-DT-COMP3  
Move WD-3CHARS-DT-COMP3           to  file-variable -->  X(03)         

我没有在输出中获得所需的值。 怎么办呢?

3 个答案:

答案 0 :(得分:3)

你也想要打开"解包"您的日期稍后会在另一个程序中使用,所以使用REDEFINES而不是具有从属压缩十进制的组:

       05  WD-DDMMYY-DT-NUMERIC             PIC 9(06).      
       05  WD-DDMMYY-DT-PD PACKED-DECIMAL   PIC 9(06)V9
                                              VALUE ZERO.
       05  FILLER 
             REDEFINES
               WD-DDMMYY-DT-PD.
           10  WD-BCD                       PIC X(03).
           10  FILLER                       PIC X.

       MOVE WD-DDMMYY-DT-NUMERIC     TO WD-DDMMYY-DT-PD
       MOVE WD-BCD                   TO wherever-you-want

打包十进制字段的低位半字节(nybble)表示操作符号(C表示正数,D表示负数,F表示无操作符号,视为正数 - 有一些非首选符号为好吧,A,B,E)。

对于压缩十进制的数字部分,一位数字需要一个nybble。

对于压缩十进制,任何给定数量的字节将允许奇数位数准确拟合。偶数个数字必须始终以零为前提(您不必担心,编译器会为您执行此操作)。

获得六位小数"打包"在三个字节中,您必须忽略该符号(记住即使对于无符号字段也使用nybble)。该结果是一种称为二进制编码十进制(BCD)的约定。 COBOL没有BCD的原生支持,所以你必须编码。但并不多。

要让标志脱离,您需要将数字移到左边的一个nybble,同时留下你的标志。单独留下标志不是问题,COBOL会为您做到这一点。向左移动就像是乘以10的幂。向左移动一个,乘以10。

但是,有一种更简洁的方式来安排移位,即将压缩十进制字段定义为具有一个小数位(V9)。当你的日期(显然是一个整数)被移到这个字段时,小数部分将为零(一位数),日期日期将在零之前。

值得注意的是,对于IBM的企业COBOL V5,任何乘以或除以10的幂实际上都是实现适当的转换。

这意味着V5编译器生成的代码对于MULTIPLY 10和MOVE到一个小数位的字段非常相似。也许是相同的(我无法检查)。

To" unpack"日期:

       05  WD-DDMMYY-DT-NUMERIC             PIC 9(06).      
       05  WD-DDMMYY-DT-PD PACKED-DECIMAL   PIC 9(06)V9
                                              VALUE ZERO.
       05  FILLER 
             REDEFINES
               WD-DDMMYY-DT-PD.
           10  WD-BCD                       PIC X(03).
           10  FILLER                       PIC X.

       MOVE wherever-you-want        TO WD-BCD
       MOVE WD-DDMMYY-DT-PD          TO WD-DDMMYY-DT-NUMERIC

请注意此定义中的VALUE ZERO。这就是Enterprise COBOL的工作方式(无论如何最多为V4.2),实际上并不是必需的,但它是程序员的纪录片。低位字节(第四个)永远不会从它的初始值改变,这意味着它总是包含X' 0F'。编译器实际上会"短路"这个,因为无论如何它都会强制输出无符号,因此不需要来自源字段的符号。

答案 1 :(得分:3)

Bills 回答是正确的,但我会尝试使用日期150131(2015年1月31日)提供更直观的答案

如果您将该字段声明为

  05  WD-DDMMYY-DT-NUMERIC             PIC 9(06) comp-3.  

然后150131以 x'01 50 13 1c'存储在WD-DDMMYY-DT-NUMERIC中,占用4个字节。但是如果你宣布像

那样的字段
  05  WD-DDMMYY-DT-NUMERIC             PIC 9(06)V9 comp-3.  
  05  FILLER    REDEFINES      WD-DDMMYY-DT-PD.
      10  WD-BCD                       PIC X(03).

然后150131存储在WD-DDMMYY-DT-NUMERIC中 x'15 01 31 0c'再次占用4个字节,但WD-BCD保持 x'15 01 31 ',它包含所有日期,长度为3个字节

答案 2 :(得分:0)

01 WORKING-VARIABLES.
 03  WD-DDMMYY-DT-NUMERIC         PIC 9(06).      
 03  WD-3CHARS-DT-COMP3-X.
     05 WD-DDMMYY-DT-COMP3        PIC 9(08) COMP-3.
 03  FILLER REDEFINES WD-3CHARS-DT-COMP3-X.
     05 FILLER                    PIC X(01).
     05 WD-3CHARS-DT-COMP3        PIC X(03).


MOVE 311216                     TO WD-DDMMYY-DT-NUMERIC.
MULTIPLY WD-DDMMYY-DT-NUMERIC
  BY 10                     GIVING WD-DDMMYY-DT-COMP3.
Move WD-3CHARS-DT-COMP3         to FILE-O-FIELD.

应该解决你的问题。