I need to write code in python which will convert packed decimal data to zoned decimal or decimal data.If anybody already have written function for it please help me with it.
Thanks in Advance.
I need to write code in python which will convert packed decimal data to zoned decimal or decimal data.If anybody already have written function for it please help me with it.
Thanks in Advance.
It depends on how are you storing the packaged data, but definitely the best way to do it is coding a COBOL decoder from COMP-3 to numeric or alphanumeric, It will simply be:
01 WS-YOUR-COMP-DATA PIC 9(xx) COMP-3.
01 WS-NUMERIC-VAR 9(xx).
...
PROCEDURE DIVISION.
* ---> here you read your data
* ---> then convert it:
MOVE WS-YOUR-COMP-DATA TO WS-NUMERIC-VAR.
* ---> and finally, you send it or write it into your dataset/queue/DB.
Although, if you can't nor want to do it, here are some options determined by how are you saving the data:
import ebcdic
file = open("your-file.txt",'r')
for line in file:
#Usually the cp1141 is for Austria, Germany, Switzerland characters.
bline = line.encode('cp1141')
print(bline.hex())
file.close()
INPUT:
FD FILEO
RECORDING MODE IS F.
01 FILEO-REC PIC S9(10) COMP-3.
01 FILEO-REC1 PIC S9(09) COMP-3.
01 FILEO-REC2 PIC 9(09) COMP-3.
01 FILEO-REC3 PIC 9(10) COMP-3.
WORKING-STORAGE SECTION.
01 FS-FILEO PIC 9(02).
88 FS-FILEO-OK VALUE 00.
01 WS-COUNT PIC 9(02).
01 WS-I PIC 9(02).
01 WS-MY-VAR OCCURS 0 TO 10 TIMES DEPENDING ON WS-COUNT
PIC S9(10) COMP-3.
PROCEDURE DIVISION.
MAIN-PROCEDURE.
MOVE 4 TO WS-COUNT
MOVE 0123456789 TO WS-MY-VAR(1)
MOVE 123456789 TO WS-MY-VAR(2)
MOVE ZEROES TO WS-MY-VAR(3)
MOVE -123456789 TO WS-MY-VAR(4)
*Now we test with each of the four option in every record structure.
OUTPUT with S9(10):
00123456789c
00123456789c
00000000000c
00123456789d
OUTPUT with S9(09):
123456789c
123456789c
000000000c
123456789d
OUTPUT with 9(09):
123456789f
123456789f
000000000f
123456789f
OUTPUT with 9(10):
00123456789f
00123456789f
00000000000f
00123456789f
As you can see, the character printed are exactly the same, but a letter is added at the end. This character could be 'd' if the number is negative signed, 'c' if it is positive signed or 'f' if the number is not signed. These final character only appear as filler when the length is odd. Ex. 9(07) is odd, 7 divided by 2 is 3.5, rounded to 4 and filling the 0.5 space with the letter. Anyway, I saw in my test that OpenCOBOL don't follow this rule and fill ever.
To find your encoding cpxxxx value look in this table or in your emulate terminal or COBOL IDE (openCOBOL indicate it in the bottom right corner).
bline = line.encode('cp1141')
for bline = bytes(line, 'ascii')
I let you both programs python and COBOL in this GitHub repo.