Mon 6 Aug 2007
Most programmers claim to understand but can’t explain it. The vendors I dealt with in China and Dubai claims to able to do it, and then repented.
I don’t get it. What is so hard about IBM packed fields?
Packed field is an efficient way to store numbers, maybe not as efficient as an int but it’s commonly used on the IBM AS/400 platform.
Digits 123 can be represented in ASCII hex 313233 or in EBCDIC hex as F1F2F3. Packed field stores the number directly as hex 123F, which is neither ASCII nor EBCDIC. This shortens the size required to store digits. The last nibble (half of a byte) can be either D or F representing a negative or positive integer.
The obvious benefit is of course, if you’re paying your bandwidth by the number of bytes you’re transmitting, you’d want the data compressed. Packed fields keep numeric fields’ size small.
Someone asked me, assuming you know it’s a packed field with certain length, how do you test for a valid packed value?
This is what I came up with in ILE RPG:
*
H BndDir('QC2LE')
*
D getHex Pr ExtProc('cvthc')
D 1A
D 1A
D 10I 0 Value
*
* Use with entry parameters
D pValue S 20A
D pResult S 1N
*
* Use with working fields
D Ds
D xHex 40A Inz(*Blanks)
D xHexS 2S 0 Dim(20) Overlay(xHex:1)
D xHexA 2A Dim(20) Overlay(xHex:1)
*
D xLen S 5U 0 Inz(*Zeros)
D xPos S Like(xLen) Inz(*Zeros)
D xVal S Like(xLen) Inz(*Zeros)
*
D cNumeric C Const('0123456789')
D cYes C Const(*On)
D cNo C Const(*Off)
*
C *Entry Plist
C Parm pValue
C Parm pResult
*
C Movel(P) cNo pResult
C Eval xLen = %CheckR(' ':pValue)
*
C If (xLen > *Zeros)
C CallP getHex(xHex:pValue:%Size(xHex))
*
C For xPos = 1 By 1 To xLen
*
C Eval xVal = %Check(cNumeric:xHexA(xPos):1)
*
C If (xVal > *Zeros) And (xPos < xLen)
* Not last byte and value contains non-numeric.
C Leave
*
C ElseIf (xPos = xLen) And
C ((%Subst(xHexA(xPos):2:1) <> ‘D’) And
C (%Subst(xHexA(xPos):2:1) <> ‘F’))
* Last byte and value contains non-acceptable
* non-numeric.
C Leave
*
C ElseIf (xPos = XLen)
C Move cYes pResult
*
C Else
* Try to ridicule the compiler.
C Monitor
C If ((xHexS(xPos) > 99) And (xPos < xLen))
C Leave
C EndIf
C On-Error
C Leave
C EndMon
C EndIf
*
C EndFor
*
C EndIf
*
C Return
*
So the final else condition isn’t really necessary, but I never did test this piece of code and I rather play it safe.
The code should be self-explained. Convert the value to hex, and start comparing byte by byte whether it contains valid numerical digits. Except for the last nibble, it must have either hex of D or F. Anything else is invalid.
Program returns true if given value is a valid packed field candidate.