Version 11 of Comp3 data conversion

Updated 2009-03-26 08:21:05 by suchenwi

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