Binary fields will NEVER cause S0C7 abend
This is demonstrated using the below COBOL code.
WORKING-STORAGE SECTION.
01 JUNK PIC X(04).
01 WS-BINARY REDEFINES JUNK PIC 9(08) COMP.
PROCEDURE DIVISION.
MOVE 'ABCD' TO JUNK.
DISPLAY 'WS-BINARY: ' JUNK WS-BINARY
ADD 1 TO WS-BINARY
DISPLAY 'WS-BINARY: ' JUNK WS-BINARY
MOVE '#$%=' TO JUNK.
DISPLAY 'WS-BINARY: ' JUNK WS-BINARY
ADD 1 TO WS-BINARY
DISPLAY 'WS-BINARY: ' JUNK WS-BINARY
WS-BINARY: 50766789
WS-BINARY: 69589118
WS-BINARY: 69589119
'ABCD' is indirectly moved to WS-BINARY. The hexadecimal equivalent of 'ABCD' is X’C1C2C3C4’. If you put this HEX decimal value in calculator, you will get 3,250,766,788. Since picture clause of WS-BINARY is 9(8), the last 8 digit 50,766,788 is displayed in the first DISPLAY statement.
When you add 1 to this value(3,250,766,788), it become 3,250,766,789 and second DISPLAY statement displays last 8 digits which is 50,766,789.
Case 2: Value "#$%="
'#$%=' is indirectly moved to WS-BINARY. The hexadecimal equivalent of '#$%=' is X’7B5B6C7E’. If you put this HEX decimal value in calculator, you will get 2,069,589,118. Since picture clause of WS-BINARY is 9(8), the last 8 digit 69,589,118 is displayed in the third DISPLAY statement.
When you add 1 to this value(2,069,589,118), it become 2,069,589,119 and fourth DISPLAY statement displays last 8 digits which is 69,589,119.
Typical zoned decimal declarations in COBOL are shown below:
01 WS-NUMBER1 PIC 9(5). -> Unsigned zoned decimal
01 WS-NUMBER1 PIC 9(5)V99. -> Unsigned zoned decimal
01 WS-NUMBER2 PIC S9(5)V99. -> Signed zoned decimal
Internal representation of Zoned Decimal in Memory
In a zoned decimal field:
- Each decimal digit occupies one byte.
- Each byte has 2 nibbles, and each nibble has 4 bits.
- The high-order 4 bits (zone portion) of each byte will always have b’1111’ (hex F) except the last byte.
- The low-order 4 bits (decimal portion) contain the actual numeric digit (0–9).
- In the last byte, first 4 bits will store the sign and second 4 bits will store the last numeric digit.
|
Value |
Internal Hex Representation |
|
Unsigned 12345 |
X'F1F2F3F4F5' |
|
+12345 |
X'F1F2F3F4A5' X'F1F2F3F4C5' X'F1F2F3F4E5' |
|
-12345 |
X'F1F2F3F4B5' X'F1F2F3F4D5' |
Sign is stored in the zone portion (high-order 4 bits) of the last byte. Valid signs are given below
|
Sign |
Zone Nibble |
|
Unsigned |
F |
|
Positive |
A,C,E |
|
Negative |
B,D |
01 WS-9 PIC S9(05).
01 WS-X REDEFINES WS-9 PIC X(05).
PROCEDURE DIVISION.
PARA1.
MOVE X'F1F2F3F4F5' TO WS-X
PERFORM CHECK-SIGN
MOVE X'F1F2F3F4A5' TO WS-X
PERFORM CHECK-SIGN
MOVE X'F1F2F3F4C5' TO WS-X
PERFORM CHECK-SIGN
MOVE X'F1F2F3F4E5' TO WS-X
PERFORM CHECK-SIGN
MOVE X'F1F2F3F4B5' TO WS-X
PERFORM CHECK-SIGN
MOVE X'F1F2F3F4D5' TO WS-X
PERFORM CHECK-SIGN
GOBACK.
CHECK-SIGN.
IF WS-9 > 0
DISPLAY WS-9 ' POSITIVE'
ELSE
IF WS-9 = 0
DISPLAY WS-9 ' ZEROS'
ELSE
DISPLAY WS-9 ' NEGATIVE'
END-IF
END-IF.
ADD 1 TO WS-9
DISPLAY 'WS-X : ' WS-X.
|
Output of the program is given below |
Hex value for the number displayed |
|
12345 POSITIVE |
X'F1F2F3F4F5' |
|
WS-X : 1234F |
X'F1F2F3F4C6' |
|
1234v POSITIVE |
X'F1F2F3F4A5' |
|
WS-X : 1234F |
X'F1F2F3F4C6' |
|
1234E POSITIVE |
X'F1F2F3F4C5' |
|
WS-X : 1234F |
X'F1F2F3F4C6' |
|
1234V POSITIVE |
X'F1F2F3F4E5' |
|
WS-X : 1234F |
X'F1F2F3F4C6' |
|
1234§ NEGATIVE |
X'F1F2F3F4B5' |
|
WS-X : 1234M |
X'F1F2F3F4D4' |
|
1234N NEGATIVE |
X'F1F2F3F4D5' |
|
WS-X : 1234M |
X'F1F2F3F4D4' |
Typical packed decimal declarations in COBOL are shown
below:
01 WS-NUMBER1 PIC 9(5) COMP-3.
-> Unsigned packed decimal
- Each byte has two decimal digits except the last byte
- In the last byte, first 4 bits will store the numeric digit and second 4 bits will store the sign.
- If an odd number of digits exists, the unused high-order nibble is padded with zero.
|
Value |
Internal Hex Representation |
|
Unsigned 12345 |
X'12345F' |
|
+12345 |
X'12345A' X'12345C’ X'12345E’ |
|
-12345 |
X'12345B' X'12345D’ |
|
+123456 |
X’0123456C’ |
Similar to zoned decimal, system always uses “C” for positive signs and “D” for negative signs for packed decimals, but still accepts A,B,E signs
01 JUNK PIC X(04).
01 WS-ZONED-DECIMAL REDEFINES JUNK PIC 9(04).
PROCEDURE DIVISION.
MOVE 'ABCD' TO JUNK.
DISPLAY 'WS-ZONED-DECIMAL: ' WS-ZONED-DECIMAL
ADD 1 TO WS-ZONED-DECIMAL
DISPLAY 'WS-ZONED-DECIMAL: ' WS-ZONED-DECIMAL
MOVE X'1A1B1C1D' TO JUNK.
DISPLAY 'WS-ZONED-DECIMAL: ' WS-ZONED-DECIMAL
ADD 1 TO WS-ZONED-DECIMAL
DISPLAY 'WS-ZONED-DECIMAL: ' WS-ZONED-DECIMAL
GOBACK.
WS-ZONED-DECIMAL: 1235
WS-ZONED-DECIMAL: X'1A1B1C1D'
Code Explanation
Mainframe does not have any instruction to perform arithmetic operations on zoned decimals. So, it first converts zoned-decimals to packed-decimal and then performs arithmetic operations on the packed-decimal.
The first move indirectly populated ‘ABCD’(hex value X’C1C2C3C4’) to WS-ZONED-DECIMAL.
Before adding one to WS-ZONED-DECIMAL, Value X’C1C2C3C4’ need to be converted to packed-decimal.
How Zoned Decimal to Packed Decimal Conversion Works
During the conversion process:
- The digit portion of each zoned-decimal byte is treated as a numeric digit.
- The zone bits are ignored except in the rightmost byte.
- The zone bits of the last byte become the sign nibble.
- Digits are packed together from left to right.
- If the packed-decimal result contains an unfilled nibble, it is padded with zero on the left.
Example 1: ‘ABCD’ - X'C1C2C3C4'
Value X’C1C2C3C4’ becomes X‘01234C’ after zoned-decimal to packed-decimal conversion.
Therefore, the second DISPLAY statement shows 1235, because the temporary packed-decimal representation (X'01234C') was successfully incremented by one during the arithmetic operation.
Example 2: X'1A1B1C1D'
Value X'1A1B1C1D' becomes X‘0ABCD1’ after zoned-decimal to packed-decimal conversion.
Since X‘0ABCD1’ does not adhere to packed-decimal representation, when we tried to add one to it, system produced S0C7 abend
As discussed earlier, a packed-decimal field must conform to the valid packed-decimal format. If the field contains invalid digits or an invalid sign nibble and an arithmetic operation is attempted on it, the processor detects the invalid data and raises an S0C7 (Data Exception) abend.
No comments:
Post a Comment
Note: Only a member of this blog may post a comment.