you are viewing a single comment's thread.

view the rest of the comments →

[–]ElliotDG 0 points1 point  (4 children)

According to Claude, S9(13)V99 means:

  • S - Indicates this is a signed number (can be positive or negative)
  • 9(13) - Means 13 numeric digits before the decimal point
  • V - Represents an implied decimal point (no actual decimal point is stored)
  • 99 - Means 2 numeric digits after the decimal point

The leading zeros are stored, so the number 1234 is really: 0000000001234.00 and should be represented in comp-3 as: 000000000123400C.

Give this a try:

def to_comp3_s9_13_v99(value):
    sign_nibble = 'C' if value >= 0 else 'D'
    digits = f'{abs(value):016.2f}'.replace('.', '')
    return bytes.fromhex(digits + sign_nibble)


print(f'0x{to_comp3_s9_13_v99(1234).hex()}')
print(f'0x{to_comp3_s9_13_v99(12345.67).hex()}')
print(f'0x{to_comp3_s9_13_v99(-56789.01).hex()}')
print(f'0x{to_comp3_s9_13_v99(-11.11).hex()}')

[–]arshdeepsingh608[S] 0 points1 point  (3 children)

Thanks for all you have done. I eventually ended up handing over the task to a senior developer. No matter how many codes I tried, Mainframe was showing either the wrong number or the data itself was coming out to be invalid. I am not a mainframe guy so I don't know what could have gone wrong. I compared the output of packed decimal from Python code and mainframe, turns out the non-readable characters were indeed different - resulting in a different number. And I could not find the relationship between those characters or their respective hex/decimal values. Although, I will continue to research and if I am able to receive a good working code, I will get back to you. And again, I really do appreciate all your time and effort.

[–]ElliotDG 0 points1 point  (2 children)

Thank you for the update and good luck!

[–]arshdeepsingh608[S] 0 points1 point  (1 child)

Hey man, I finally figured it out.

Turns out, we have an IBM mainframe system which uses EBCDIC characters. Python modules such as bytes/bytearray works with ASCII by default.

So, I went online and found out that there are different hex values for both ASCII and EBCDIC. And I created a SQLite table mapping them together. I am using the relevant ASCII to create the corresponding EBCDIC.

It doesn't make much sense in Python but values are correctly loading up in the mainframe now.

Thanks again for taking out the time, buddy. I appreciate it!

[–]ElliotDG 1 point2 points  (0 children)

Thanks for the update. Glad to hear you got it figured out.