2

我有一个要求,我想将数字格式的日期(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)         

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

4

3 回答 3

3

账单答案是正确的,但我会尝试使用日期 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 个字节长

于 2016-02-05T22:37:56.547 回答
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 , 是)。

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

对于压缩十进制,任何给定的字节数都将允许奇数位精确匹配。偶数位数必须始终以零开头(您不必担心,编译器会为您完成)。

要将六位十进制数字“打包”成三个字节,您必须忽略符号(请记住,即使对于无符号字段也使用 nybble)。此结果是一种称为二进制编码十进制 (BCD) 的约定。COBOL 没有对 BCD 的本机支持,因此您必须编写代码。但并不多。

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

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

值得注意的是,对于 IBM 的 Enterprise COBOL V5,任何乘以 10 的幂或除以 10 的幂实际上都被实现为适当的移位。

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

要“解包”日期:

       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'。编译器实际上会“短路”它,因为无论如何它都会强制输出无符号,所以不需要源字段的符号。

于 2016-02-05T17:39:45.853 回答
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.

应该可以解决您的问题。

于 2016-02-05T12:36:20.533 回答