hexcobolcomp-3

Cobol COMP-3 value changes after write to dataset


SOLVED

I found this line buried much past where I am moving these values to the output file:

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

changing my X'00' to X'40', which is where I'm getting the mysterious '4'. I will attribute this to my first Cobol version of the missing ";".

Thank you to Bruce and anonymous user user9835153 for your help!


I need some help with a strange scenario I've never encountered before.

I have an unsigned zoned decimal numeric as input, PIC 9(3).9(6), and I need to write it out to a dataset as a signed COMP-3, PIC S9(3)V9(6). This works fine for all values except when zeros surround the decimal in the input. The 0 before the decimal is always changed to 4 in this case.

Example: when the input value is 31.006261, it gets written as +31.006261 (x'031006261C' in the actual output file). But, when the input value is 30.006261, it is written out to the file as +34.006261 (x'034006261C').

I cannot change the how the value comes in, but I can change the input layout. I have tried a variety of ways of moving this value, including: moving straight to COMP-3 from input, moving to different types of temp fields in working storage, making the input a character field and moving to numeric (ignoring the decimal completely).

Here's a simplified version of what I'm doing:

* 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

However, when I open the output file with HEX ON here's what I get:

----+
04021
3066C  

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

This happens EVERY time zeros surround the decimal. I used a subset of data, of 8 records, and changed half to 10.1xxxxx and the other half to 10.0xxxxx (x's are various numbers). All 10.0xxxxx records changed to 14.0xxxxx but the 10.1xxxxx records stayed as correct. Did this with 20.x, 30.x, 40.x, etc. and got the same results.

I have also tried COMPUTE instead of MOVE when going from unsigned to signed -- same results. Like I mentioned before, I tried various methods of moving the input values but the results are always the same. I thought maybe part of the explicit decimal (x'4B') was somehow getting placed in the upper nibble, so I modified the input to read it separately, and changed it's hex values to x'00', but that didn't work either. I'm completely lost as to what else to try and can't find anyone else that's experienced this.

Any ideas or suggestions as to why the 0 before the decimal is getting replaced by 4?

Edit 5/21/18 after a suggestion was provided:

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

The zero before the decimal still changes after writing to dataset.


Solution

  • Here is a complete COBOL program compiled and run under IBM Enterprise COBOL for z/OS 4.2.0. It does not display the behaviour that you have described:


       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 ********************************
    

    and OFILE content displayed in hex:

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

    It all looks good to me! I think you must have some other problem buried in your code somewhere.