Search code examples
ebcdic

Is 0000 a valid EBCDIC signed value?


We have an ASCII file with numbers formatted as EBCDIC signed fields.

Sometimes the value is 0000 while I would expect 000{ or 000}.

Is 0000 a valid EBCDIC signed value within an ASCII file?


Solution

  • Short Answer

    Yes, both '0000' and '000{' denote a positive zero. '000}' denotes a negative zero.

    Detailed Answer

    Packed decimal number are often used on IBM mainframe systems, since the processor has a set of decimal instructions. Those instructions assume that its operands follow the rules for decimal packed numbers in storage. See IBM z/Architecture Principles of Operation, Chapter 8 "Decimal Instructions".

    In summary, a decimal packed number has digits, i.e. 0x0 - 0x9, in every nibble of every byte, except for the right nibble in the rightmost byte (rightmost nibble). The rightmost nibble holds the sign, which has preferred values 0xC for positive, and 0xD for negative values. The system also accepts 0xA, 0xE, and 0xF as positive signs, and 0xBas negtive sign.

    Making Packed Decimal Human Readable

    If you need to make a decimal packed number human readable, you can use the UNPK (unpack) processor instruction. This instruction transforms each byte, except for the rightmost byte, nibble by nibble, to the corresponding EBCDIC character digit, i.e.

    • 0x0 --> '0' (= 0xF0)
    • 0x1 --> '1' (= 0xF1)
    • ...
    • 0x9 --> '9' (= 0xF9)

    The rigtmost byte is handled differently, since it contains a digit in the left nibble and the sign in the right nibble. This byte is transformed by simply exchanging the nibbles. For decimal numbers with preferred sign values, this is:

    • positive values: 0xdC --> 0xCd
    • negative values: 0xdD --> 0xDd

    where the lowercase d denotes the digit nibble value, i.e. 0x0, 0x1, ..., 0x9.

    So, positvie values lead to:

    • 0xC0, 0xC1, ..., 0xC9

    and negative values lead to

    • 0xD0, 0xD1, ..., 0xD9.

    The corresponding resulting EBCDIC characters

    • '{', 'A', 'B', ..., 'I' (positive values)
    • '}', 'J', 'K', ..., 'R' (negative values)

    To make the numbers really human readable, programs then usually overlay the left nibble of this last character with 0xF to make it a read EBCDIC character digit. This is called zoned decimal format.

    So far, only the preferred sign codes were used. If alternate sign codes (as noted above) would be used, all sorts of additional characters might appear. For example, variations of the number zero with alternate sign codes would show (in EBCDIC):

    • positive zero: 0x0A --> 0xA0, which is 'µ'
    • positive zero: 0x0E --> 0xE0, which is '\'
    • positive zero: 0x0F --> 0xF0, which is '0'
    • negative zero: 0x0B --> 0xB0, which is '^'

    Handling Imporperly Unpacked Numbers

    If the program doing the unpacking of packed decimal numbers does not handle the sign nibble correctly for human redability, you can:

    • In EBCDIC, overlay the left nibble of the right most character byte with 0xF to make sure it is a real EBCDIC character digit.
    • In ASCII, overlay the left nibble of the right most character byte with 0x3 to make sure it is a real ASCII character digit.