This document provides information about converting "unsigned packed" data coming from non-IBM iSeries platforms. One example given is the Mainframe IBM zSeries machines that support a data type "unsigned packed."
Resolving the problem
Mainframe IBM zSeries machines support a data type unsigned packed, which is analogous to type packed on the IBM System i products except for the lack of a sign; signed packed numbers contain a sign in the lowest-order half-byte (hexadecimal F for "+", D for "-"). For example, the hexadecimal representation for the signed packed numbers +123456 and -123456 is, respectively, X'0123456F' and X'0123456D'.
In unsigned packed format, the number 123456 looks like this:
Given an n-digit packed field, the amount of storage S (in bytes) required for that field is:
|S = (n DIV 2) + 1||signed packed|
|S = (n DIV 2) + 1||unsigned packed, n odd|
|S = n DIV 2||unsigned packed, n even|
where DIV is integer division.
When importing data from zSeries to the System i, the issue of converting unsigned packed data to signed packed may arise. The following ILE RPG sample illustrates an algorithm to perform the conversion.
ILE RPG Source
* Input file imported from mainframe. To simplify this example, the file's record format is
* assumed to include a single field, of type character and length 3. The field in question
* really contains a 6-digit unsigned packed value.
Funspackpf if e disk
* Output file to contain the signed packed equivalents of the unsigned packed values
* imported from mainframe.
Fsgnpackpf o e disk
* The data structure below is used as follows:
* (1) The unsigned packed value is read from the input file and moved into fld1.
* (2) fld2 contains X'0F', which is used to append a positive sign to the number.
* (2) fld3, which overlays fld1 and fld2, then contains the signed version of the original
* number, multiplied by 10. For example, if fld1 is set to X'123456' (unsigned 123456
* from mainframe), then fld3 contains the number +1234560
* (3) Dividing fld3's contents by 10 eliminates the excess 0 digit on the right, while
* keeping the X'F' (positive sign).
Dfld1 1 3a
Dfld2 4 4a inz(X'0F')
Dfld3 1 4p 0
* Read unsigned packed number imported from mainframe.
C read unspackrec
* Append X'0F' to the number to make it signed (positive).
C move unspackfld fld1
* Divide by 10 to remove excess 0 digit.
C eval sgnpackfld = fld3 / 10
* Write signed packed number to output file.
C write sgnpackrec
C eval *inlr = *on
DDS for input file
A R UNSPACKREC
A UNSPACKFLD 3A
DDS for output file
A R SGNPACKREC
A SGNPACKFLD 6P 0