Version 12 of Comp3 data conversion

Updated 2009-03-26 12:45:44 by jscottb

Function to convert comp3 packed decimal data (aka BCD) (see [L1 ]) to a string.

Note: This function assumes it's signed data.

 proc comp3tostring {packed_dec_data data_len} {
    set val 0
    set ret_sign {}

    for {set byte_ndx 0} {$byte_ndx < $data_len} {incr byte_ndx} {
       scan [string index $packed_dec_data $byte_ndx] %c byte
       set byte [format "%02.2x" $byte]
       if {$byte_ndx == [expr {$data_len - 1}]} {
          append val [format "%x" [string index $byte 0]]
          if {[string index $byte 1] == {d}} {
             set ret_sign {-}
          }
       } else {
          append val "[format "%x%x" [string index $byte 0] [string index $byte 1]]"
       }
    }

    return "$ret_sign$val"
 }

RS 2009-03-24: Here's a simpler alternative:

 proc comp3int x {
    binary scan $x H* hex
    set digits [string range $hex 0 end-1]
    set sign [string index $hex end]
    scan $digits %d int
    switch -- $sign {
       c {}
       d {set int -$int}
       default {return -code error "bad comp3 number: $x"}
    }

    return $int
 }

Richard, after looking at the code again, I see you include the sign digit as part of the numbers value. This function would work fine on unsigned data but not signed. Made changes to make that one work.


RS Of course it worked before I posted it... (tested with the examples on the page linked above). I use scan for two purposes: strip off leading zeroes except maybe a single one, and: stop parsing at the first non-decimal character (the last char can according to spec only be "c" or "d"). Demo:

 % scan 01234d %d
 1234

JSB I will test more with it as time permits. I did run it in some code I have that converts big iron DB2 load files to MS Sql server BCP data and it gave bad results on some data. Once I get this project behind me I will revisit.