Updated 2012-06-27 11:14:38 by RLE

Bitstrings are one way of Working with binary data, and are particularly useful for communications. Tcl's binary format and binary scan commands make it easy to convert values into binary strings, but they aren't exactly matched with the concept of an arbitrarily long string of bits. In this case, you want to set or get a single bit from the long string. These two procedures make it easy to compose bit strings.
``` #  bitstringSet and bitstringGet
#
#  These two procedures simplfy access to single bits
#  of arbitrary bit strings.
#

proc bitstringSet {string position bit} {

#  Check parameters
if { (! [string is integer \$position]) || (\$position < 0) } {
error "position must be an integer >= 0"
}
if { (\$bit ne "0") && (\$bit ne "1") } {
error "bit must be '0' or '1'"
}

#  Compute byte and bit offsets
set bytenum [expr \$position / 8]
set bitnum [expr \$position % 8]

#  Scan the btye from the string
#  Default value is used if scan fails
set byteval "00000000"
binary scan \$string @\${bytenum}b8 byteval

#  Compute new string of zeros and ones
set newbyte [string range \$byteval 0 [expr \$bitnum-1]]\$bit[string range \$byteval [expr \$bitnum+1] end]

#  Convert back into binary format
return [binary format a*@\${bytenum}b8 \$string \$newbyte]
}

proc bitstringGet {string position} {

#  Check parameters
if { (! [string is integer \$position]) || (\$position < 0) } {
error "position must be an integer >= 0"
}

#  Compute byte and bit offsets
set bytenum [expr \$position / 8]
set bitnum [expr \$position % 8]

#  Scan the btye from the string
#  Default value is used if scan fails
set byteval "00000000"
binary scan \$string @\${bytenum}b8 byteval

# return the interesting bit
return [string range \$byteval \$bitnum \$bitnum]
}```