[comp.lang.icon] Procedures for packed decimal conversions

tenaglia@mis.mcw.edu (Chris Tenaglia - 257-8765) (01/05/90)

Dear Icon-Group,

Here are two other interesting procedures. pack() and unpack() deal
with translating numbers to and from a packed decimal format. Packed
format is used to de/compress decimal numbers. The packed numbers use
just over 1/2 the space of ascii formatted numbers. I use the format
for experiments with encryption. Sometimes databases may use them.
unpack() requires radcon() from the icon program library. Perhaps
someone would care to improve on my code either in performance or
elegance? pack(num,width) packs a number into a packed decimal string.
num is the number and width is the size of the target packed string.
unpack(val,width) unpacks a packed decimal number into an integer.
width is the width of the returned integer.

##################################################################
#                                                                #
# THIS PROCEDURE PACKS AN INTEGER IN TO PACKED DECIMAL STRING.   #
#                                                                #
##################################################################
procedure pack(num,width)           # 5p
  local int,sign,prep,packed,i,word,calc
  (int := integer(num)) | fail                
  if int < 0 then sign := "=" else sign := "<"
  prep := int || sign ; packed := ""
  if (*prep % 2) ~= 0 then prep := "0" || prep
  every i := 1 to *prep by 2 do
    {
    word := prep[i+:2]
    if word[-1] == ("=" | "<") then
      {
      calc     := word[1]*16 + ord(word[2])-48
      packed ||:= char(calc)
      next
      }
    calc     := word[1]*16 + word[2]
    packed ||:= char(calc)
    }
  /width := *packed
  return right(packed,width,"\0")
  end                                   

##################################################################
#                                                                #
# THIS PROCEDURE UNPACKS A VALUE INTO AN INTEGER.                #
#                                                                #
##################################################################
procedure unpack(val,width)         # 6p     REQUIRES LINK RADCON !
  local tmp,number,tens,ones,sign
  tmp := "" ; sign := 1
  every number := ord(!val) do
    {
    hex := map(radcon(number,10,16),&lcase,&ucase)
    tmp ||:= hex
    }
  if tmp[-1] == ("B" | "D") then sign := -1
  tmp[-1] := "" ; tmp *:= sign ; /width := *tmp
  return right(tmp,width)
  end

Have Fun !

Chris Tenaglia (System Manager)
Medical College of Wisconsin
8701 W. Watertown Plank Rd.
Milwaukee, WI 53226
(414)257-8765
tenaglia@mis.mcw.edu