Значение Cobol COMP-3 изменяется после записи в набор данных - PullRequest
0 голосов
/ 18 мая 2018

РЕШЕНО

Я обнаружил, что эта строка скрыта намного дальше, куда я перемещаю эти значения в выходной файл:

INSPECT OUT-RECORD REPLACING ALL X'00' BY ' '

, изменяя мой X'00 'на X'40', чтовот где я получаю загадочную «4».Я приписываю это моей первой версии Cobol пропавшего ";".

Спасибо Брюсу и анонимному пользователю user9835153 за помощь!


Мне нужна помощь со странным сценарием, с которым я никогда не сталкивался раньше.

В качестве входных данных у меня есть зонное десятичное число без знака, PIC 9 (3) .9 (6), и мне нужно записать его в набор данных как подписанный COMP-3, PIC S9 (3) V9(6).Это прекрасно работает для всех значений , за исключением случаев, когда нули окружают десятичную дробь на входе .В этом случае 0 перед десятичной дробью всегда изменяется на 4.

Пример: , когда входное значение равно 31.006261, оно записывается как +31.006261 (x'031006261C 'в фактическом выходе)файл).Но когда входное значение равно 30.006261, оно записывается в файл как +34.006261 (x'034006261C ').

Я не могу изменить способ ввода значения, но я могу изменить формат ввода.Я пробовал различные способы перемещения этого значения, в том числе: переход прямо к COMP-3 из ввода, переход к различным типам временных полей в рабочем хранилище, создание ввода символьным полем и переход к числовому (полностью игнорируя десятичное число),

Вот упрощенная версия того, что я делаю:

* Value 30.006261 is read into WS-IN-VAL from input file. 

01 WS-IN-RECORD.
   05 WS-IN-VAL      PIC 9(3).9(6).

01 OUT-RECORD.
   05 WS-OUT-VAL     PIC S9(3)V9(6) COMP-3.

* Working Storage 01 area
   05 WS-HOLD-VAL       PIC 9(3)V9(6).
   05 WS-DISP-VAL       PIC +9(3).9(6).

MOVE WS-IN-VAL   TO WS-HOLD-VAL.
MOVE WS-HOLD-VAL TO WS-OUT-VAL.
MOVE WS-OUT-VAL  TO WS-DISP-VAL.

WRITE WS-OUT-RECORD.

DISPLAY 'VALUE IN:   ' WS-IN-VAL.                
DISPLAY 'HOLD VALUE: ' WS-HOLD-VAL.
DISPLAY 'VALUE OUT:  ' WS-OUT-VAL.
DISPLAY 'FORMATTED:  ' WS-DISP-VAL.

VALUE IN:   30.006261                
HOLD VALUE: 030006261
VALUE OUT:  030006261
FORMATTED:  +030.006261

Однако, когда я открываю выходной файл с HEX ON, вот что я получаю:

----+
04021
3066C  

View of the file with a layout shows: +34.006261.

Это происходит КАЖДЫЙ раз, когда нули окружают десятичную дробь.Я использовал подмножество данных из 8 записей и изменил половину на 10.1xxxxx, а другую половину на 10.0xxxxx (x - это различные числа).Все записи 10.0xxxxx изменились на 14.0xxxxx, но записи 10.1xxxxx остались правильными.Сделал это с 20.x, 30.x, 40.x и т. Д. И получил те же результаты.

Я также пробовал COMPUTE вместо MOVE при переходе от неподписанного к подписанному - те же результаты.Как я уже упоминал ранее, я пробовал различные способы перемещения входных значений, но результаты всегда одинаковы.Я подумал, что, возможно, часть явного десятичного числа (x'4B ') каким-то образом помещается в верхний полубайт, поэтому я изменил ввод, чтобы прочитать его отдельно, и изменил его шестнадцатеричные значения на x'00', но это не сработалоили.Я совершенно потерян в том, что еще можно попробовать, и не могу найти никого, кто испытал это.

Есть какие-нибудь идеи или предложения относительно того, почему 0 перед десятичной дробью заменяется на 4?

Изменить 5/21/18 после предоставления предложения:

VALUE FROM FILE:              50.022287  
VALUE AFTER MOVE:             050022287
VALUE AS COMP-3 (OUTPUT FLD): 050022287
OUTPUT DISPLAYED:             +050.022287

VALUE IN FILE: +54.022287

Ноль перед десятичной дробью все еще изменяется после записи в набор данных.

Ответы [ 2 ]

0 голосов
/ 23 мая 2018

Вот полная программа COBOL, скомпилированная и запущенная в IBM Enterprise COBOL для z / OS 4.2.0.Он не отображает поведение, которое вы описали:

   IDENTIFICATION DIVISION.
   PROGRAM-ID. COMP3.
   ENVIRONMENT DIVISION.
   INPUT-OUTPUT SECTION.
   FILE-CONTROL.
        SELECT OFILE  ASSIGN TO OFILE STATUS OFILE-STAT.
   DATA DIVISION.
   FILE SECTION.
    FD  OFILE
        LABEL RECORDS STANDARD
        RECORDING MODE F
        BLOCK CONTAINS 0 RECORDS.

    01  OFILE-REC.
        02 COMP3-NBR                PIC S9(3)V9(6) COMP-3.
        02                          PIC X(75).

   WORKING-STORAGE SECTION.
   01  WS-IN-VAL                    PIC 9(3).9(6).
   01  WS-OUT-VAL                   PIC S9(3)V9(6) COMP-3.
   01  WS-OUT-VAL-X REDEFINES WS-OUT-VAL
                                    PIC X(5).
   01  WS-HOLD-VAL                  PIC 9(3).9(6).
   01  WS-DISP-VAL                  PIC +9(3).9(6).
   01  OFILE-STAT                   PIC 9(2).
       88 OFILE-STAT-OK             VALUE ZERO.
   PROCEDURE DIVISION.
       MOVE 30.006216       TO WS-IN-VAL
       MOVE WS-IN-VAL       TO WS-HOLD-VAL
       MOVE WS-HOLD-VAL     TO WS-OUT-VAL
        02                          PIC X(75).

   WORKING-STORAGE SECTION.
   01  WS-IN-VAL                    PIC 9(3).9(6).
   01  WS-OUT-VAL                   PIC S9(3)V9(6) COMP-3.
   01  WS-OUT-VAL-X REDEFINES WS-OUT-VAL
                                    PIC X(5).
   01  WS-HOLD-VAL                  PIC 9(3).9(6).
   01  WS-DISP-VAL                  PIC +9(3).9(6).
   01  OFILE-STAT                   PIC 9(2).
       88 OFILE-STAT-OK             VALUE ZERO.
   PROCEDURE DIVISION.
       MOVE 30.006216       TO WS-IN-VAL
       MOVE WS-IN-VAL       TO WS-HOLD-VAL
       MOVE WS-HOLD-VAL     TO WS-OUT-VAL
       MOVE WS-OUT-VAL      TO WS-DISP-VAL
       DISPLAY 'VALUE IN: ' WS-IN-VAL
       DISPLAY 'HOLD VAL: ' WS-HOLD-VAL
       DISPLAY 'OUT VAL : ' WS-OUT-VAL
       DISPLAY 'OUT VALX: ' WS-OUT-VAL-X
       OPEN OUTPUT OFILE
       IF NOT OFILE-STAT-OK THEN
          DISPLAY "OFILE OPEN STATUS: " OFILE-STAT
          STOP RUN
       END-IF
       INITIALIZE OFILE-REC
       MOVE WS-OUT-VAL  TO COMP3-NBR
       WRITE OFILE-REC
       IF NOT OFILE-STAT-OK THEN
          DISPLAY "OFILE WRITE STATUS: " OFILE-STAT
          STOP RUN
       END-IF
       GOBACK
       .

SYSOUT:


******************************** Top of Data ***********************************
VALUE IN: 030.006216
HOLD VAL: 030.006216
OUT VAL : 030006216
OUT VALX: : ::%
 ******************************* Bottom of Data ********************************

и содержимое OFILE, отображаемое в шестнадцатеричном формате:


****** ***************************** Top of Data ******************************
000001     %
       000260000000000000000000000000000000000000000000000000000000000000000000
       3061C0000000000000000000000000000000000000000000000000000000000000000000
------------------------------------------------------------------------------
****** **************************** Bottom of Data ****************************

Все это выглядит хорошо для меня!Я думаю, что где-то в вашем коде должна быть скрыта какая-то другая проблема.

0 голосов
/ 19 мая 2018

В более ранних версиях Cobol 9 (3) .9 (6) было бы Edited-numeric -> символьное поле.Я не уверен, что должны делать текущие реализации стандарта / IBM. Вы можете проверить в руководствах IBM / IBM, что должно было произойти.

Я бы, вероятно, закодировал бы его как

01 WS-IN-RECORD.
   05 WS-IN-VAL      PIC 9(3).9(6).
   05 redefines WS-IN-VAL.
      10 WS-IN-VAL-pt1        pic 9(3)
      10                      pic x.
      10 WS-IN-VAL-Decimal    pic v9(6)

и

    Add WS-IN-VAL-pt1         to WS-IN-VAL-Decimal
                          Giving ...

Возможный эксперимент

Попробуйте определить

01 WS-IN-RECORD.
   05 WS-IN-VAL-X.
      10 WS-IN-VAL      PIC 9(3).9(6).

и попробуйте переместить как WS-IN-VAL-X, так и WS-IN-VALи посмотреть, если результат будет таким же

...