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.
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:
SYSOUT:
and OFILE content displayed in hex:
It all looks good to me! I think you must have some other problem buried in your code somewhere.