How can I read in more than 16 digits with VISION:Results?
VISION:Results NUMERIC (zoned decimal - type NU) and Packed Decimal (type PD) are limited to 16 bytes. This limits NUMERIC fields to 16 digits and Packed Decimal fields to 31 digits. The application programmer usually has no control over the format of the input data, so if a zoned decimal field needs to be read, but the size exceeds 16 digits, a bit of maneuvering is needed.
There are multiple ways to handle this, but let's discuss one way to handle an input field 18 bytes long.
Over define the rightmost bytes of input field, and a working storage packed field.
Assume input field: 123456789012345678s
BIGNUM 18 1 ; x'F1F2F3F4F5F6F7F8F9F0F1F2F3F4F5F6F7C8'
MAJORITY 15 1 ; x'F1F2F3F4F5F6F7F8F9F0F1F2F3F4F5'
LAST3 3 16 NU ; x'F6F7C8'
WORKAREA
GOAL 16 1 PD
PACKEND3 2 15 PD
Move the high order section of the input field to a packed field, letting VISION:Results automatically convert the character digits to packed decimal format.
GOAL = MAJORITY
GOAL now contains x'123456789012345C'
Multiply the packed field by 1000 to shift the data 3 positions to the left.
GOAL = GOAL * 1000
This results in GOAL containing x'123456789012345000C'
Move the low order 3 digits to the low order 2 bytes of the packed field, allowing for 3 digits and the sign.
(Adding the fields would only work if the input data is always positive; this allows for negative values as well.)
PACKEND3 = LAST3
PACKEND now contains x'678C, so GOAL now contains x'123456789012345678C'
Putting it all together you have the following code. You can now work with GOAL for any arithmetic function needed by the application.
OPTION STRUCTURED ; NEEDED FOR DOWHILE
FILE INFILE INPUT STATUS ASTATUS
BIGNUM 18 1
MAJORITY 15 1
* MAX DIGITS ALLOWED IN NUMERIC FIELD IS 16
* BUT WE WILL MANIPULATE IN THE PACKED FIELD
* SO NEED TO ALLOW FOR THE SIGN NIBBLE
LAST3 3 16 NU
WORKAREA
GOAL 16 1 PD
PACKEND3 2 15 PD
* (LAST 2 BYTES OF PACKED NUMER HAS 3 DIGITS AND SIGN)
*
REPORT 80 WIDE
*
READREC:
READ INFILE
DOWHILE ASTATUS NE 'E'
GOAL = MAJORITY
GOAL = GOAL * 1000
* MOVE HIGH ORDER SEGMENT TO PACKED FIELD AND SHIFT LEFT BY 3
PACKEND3 = LAST3
* MOVE IN LOW ORDER DIGITS
LIST BIGNUM GOAL
READ INFILE
ENDDO
STOP
INFILE content:
00123456789012345H
01123456789012345H
12345678901234567H
12345678901234567Q
----------------
RESULTING OUTPUT
----------------
BIGNUM GOAL
00123456789012345H 1234567890123458
01123456789012345H 11234567890123458
12345678901234567H 123456789012345678
12345678901234567Q 123456789012345678-
This could be used for any NUMERIC field size up to 31 digits. The only changes are to this example are: