2

I have the following variable in COBOL program which gets its value from a file, when it is read:

01 Employee-number PIC 09(8) comp
01 Employee-number-x redefines 
   Employee-number PIC x(04)

I have another variable in the same program:

01 D-element-number PIC 9(04)

Now,

Move Employee-number to D-element-number

Then I write this D-element-number to a file

value read from input file is :

0013 
0024

so this value comes to Employee-number and Employee-number-x and I move this value to D-Element-number and write this variable to a output file.

But I get this in the output file:

4660
FFFF
4660

4660 is the decimal equivalent of X'1234'

But I want to see something like:

1234
FFFF
1234

How can I achieve this ?

I am allowed to change the definition of D-element-number but nothing else.

Bill Woodger
  • 12,968
  • 4
  • 38
  • 47
Vikas
  • 1,900
  • 1
  • 19
  • 20
  • 1
    01 D-element-number PIC 9(08) or PIC 9(09). – Gilbert Le Blanc Aug 19 '13 at 18:23
  • @GilbertLeBlanc, yes, it is a confused explanation, so it could be this simple :-) – Bill Woodger Aug 19 '13 at 20:12
  • @user2695332, why do you want to do this, and can you remove the confusion from the question. If the numbers you are showing are in "vertical hex" it would be nice to know that, especially with the 00001234, where you could also show the "."s that your normally see for "non-display" characters. Exactly what do you mean by "I am allowed to change the definition of D-element-number but nothing else" as it may not be possible without writing some other code - what then? – Bill Woodger Aug 19 '13 at 20:15
  • @user2695332, what is the value of your TRUNC option on the compile listing? If BIN you'd best have the PIC 9(9), as with TRUNC(BIN) you can get some 9-digit numbers. How big are your account numbers is the short way to tell you how long the field should be. – Bill Woodger Aug 19 '13 at 21:12

2 Answers2

3

Assuming that when you have X'00001234' you want C'00001234', have a look here. http://ibmmainframes.com/viewtopic.php?p=234231#234231

Ignore the rest of the discussion for now, just concentrate on that post.

This is the key part:

       PERFORM UNTIL X-WS-1000 > X-WS-1000-MAX
           MOVE WS-1000-BYTE-TBL (X-WS-1000)
                                   TO WS-PACKED-X (1:1)
           MOVE WS-PACKED          TO WS-DISPLAY
           MOVE WS-DISPLAY-X       TO WS-2000-BYTE-TBL (X-WS-2000)
           SET  X-WS-1000          UP BY 1
           SET  X-WS-2000          UP BY 1
       END-PERFORM

You need the exact storage definitions to go with it (don't "correct" anything).

It works by getting the compiler to use the "unpack" instruction (UNPK). This one is working one byte at a time, so simple to explain.

X'12' (an example on-byte field) is put in a two-byte field. X'12ii' (where the value of ii is "irrelevant").

UNPK will then turn this "packed" number into a "zoned" number. A "Zone" is the first four bts of a byte, and for a Zoned number, the four bits are all set to one. So you get an F. Then you get the left-most digit from the first byte. Then you get the second output byte, first four bits set to F, then the second input digit.

Then the UNPK continues with the final byte, which contains one irrelevant digit, and an irrelevant sign. For a Zoned number, the sign and right-most digit occupy the same byte (the sign in the zone) so you get a whole byte of irrelevance.

X'12' -> X'12ii' -> X'F1F1ii'.

The first two bytes of the three-byte output are C'12'.

Nos, what is all fine for numbers, but letters make a mess:

X'AB' -> X'ABii' -> X'FAFBii'

Although F and a digits gives a displayable number, for F and a letter, the result does not mean much directly.

Now the INSPECT ... CONVERTING comes to the rescue: FA gets translated to C'A' (X'C1), and the same for the letters through to F.

Your results after the CONVERTING will be C'AB'.

Should give you enough to work on.

There are other methods, but this is a fair COBOL approximation to the classic Assembler technique with UNPK and a TRANSLATE (TR) and a table of translation values.

If you use your favourite search engine. you should be able to fine more methods, using calculation (more than one), table-lookups, I've even seen a 256-WHEN EVALUATE that "works", but I guess it is a little on the "slow" side.

Thinking further, you actually have a BCD (Binary Coded Decimal) don't you? This is a Packed Decimal, without the sign. You don't have any alphas in your field.

This is even simpler to convert.

01  the-converted-value PACKED-DECIMAL PIC 9(8)V9 VALUE ZERO.
01  FILLER REDEFINES the-converted-value.
    05  the-binary-value PIC X(4).
    05  FILLER PIC X.

MOVE Employee-number-x TO the-binary-value
MOVE the-converted-value TO D-element-number (with Gilbert's correction to PIC 9(8)).

The "decimal place" is the ii, the ignore value and ignore sign. You no longer need the INSPECT ... CONVERTING ... as you only have numeric digits. If you have a BCD...

A really good way for you to have answered your own question would have been to find out how the number was created in the binary field in the first place.

Bill Woodger
  • 12,968
  • 4
  • 38
  • 47
0

Didn't try this, but I think it might work:

01 WN-GROUP.
   05 Employee-number PIC 9(8) comp.
   05 PACKED-ZERO     PIC 9(1) COMP-3 VALUE ZERO.

01 WN-PACKED redefines WN-GROUP PIC 9(9) COMP-3.
01 WN-UNPACKED PIC 9(9).

Then in your procedure:

MOVE your-number TO Employee-number
MOVE WN-PACKED TO WN-UNPACKED.

And finally you can move or display WN-PACKED(1:8).

  • Well, you should have tried it. For instance, WN-PACKED is only five bytes long, but you suggest using eight bytes. You can't reference-modify a non-DISPLAY/NATIONAL field either. What you are trying to do is covered in my answer isn't it? – Bill Woodger Sep 18 '13 at 13:54
  • Well, I tried it and it works, just needs to move WN-PACKED to an unpacked variable. I'm editing the previous code. – David Vidal Sep 18 '13 at 14:08
  • Anyway, I just realised that the question is 1 month old... haha Probably Bill's answer was enough – David Vidal Sep 18 '13 at 14:16
  • Try changing this: 01 WN-PACKED redefines WN-GROUP PIC 9(9) COMP-3. To this: 01 WN-PACKED redefines WN-GROUP PIC 9(8)V9 COMP-3. Then forget the reference-modification. The "decimal place" will get truncated when the field is MOVEd. Hah. Just noticed a field in my answer is too long... – Bill Woodger Sep 18 '13 at 14:40
  • Oh yes! that works better, no need to move positions. Didn't noticed before that your first answer was essentially that, sorry. – David Vidal Sep 18 '13 at 14:45