I want a proc:
## Convert bin to dec or hex
proc convBinToHexNib { binIn mode } {
?? code ??
if {$mode == dec} {return decimal}
if {$mode == hex} {return hex}
}
Syntax: convBinToHexNib 1100
decimal return: 12
or
hex return: C
Thanks,
- Daniel
proc convBinToHexNib { binIn {mode hex} } {
set ret error
switch -glob -- $mode \
hex* {
set val [binary format B $binIn]
binary scan H $val ret
} dec* {
set val [binary format B* 0000$binIn ]
binary scan $val c ret
} default {
puts stderr "WHAT mode? $mode"
}
return $ret
}
Thanks a million for that! Actually, it returns an error for hex mode
and displays a CTL-Char (square), rather than the hex code. The square
char doesn't print here on the browser, but I do see it in the TCL
shell window. What is this?:
% convBinToHexNib 0100 dec
4
% convBinToHexNib 0100 hex
bad field specifier "
Thanks,
- Daniel
You don't really want [binary scan/format] for this unless your're
doing [binary format] to convert the bit string to raw value and then
[binary scan] to convert it back to a number string. You can easily
convert the bitstring to a number using basic math + string
manupilation. Here's a straightforward implementation:
# This works for up to 32 bits.
# Any more and the value will roll over.
proc bin2int {binstring} {
set ret 0
foreach bit [split $binstring ""] {
set ret [expr {$ret << 1}]
if {[string is boolean $bit]} {
set ret [expr {$ret | $bit}]
} else {
error "string is not binary!"
}
}
return $ret
}
# Usage: convert nybble to decimal:
set dec [bin2int 1010]
# convert nybble to hex:
format %x [bin2int 1010]
proc convBinToHexNib {binIn mode} {
binary scan [binary format B8 0000$binIn] c1 num
switch -exact -- $mode {
dec {
set result $num
}
hex {
set result [format %x $num]
}
default {
error "Unknown mode '$mode'"
}
}
return $result
}
--
+--------------------------------+---------------------------------------+
| Gerald W. Lester |
|"The man who fights for his ideals is the man who is alive." - Cervantes|
+------------------------------------------------------------------------+
Excellent!! I'm already using it. Thanks guys.
- Daniel
> # This works for up to 32 bits.
> # Any more and the value will roll over.
> proc bin2int {binstring} {
> set ret 0
> foreach bit [split $binstring ""] {
> set ret [expr {$ret << 1}]
> if {[string is boolean $bit]} {
# this is a one funky thing!
> set ret [expr {$ret | $bit}]
> } else {
> error "string is not binary!"
> }
> }
> return $ret
> }
Unfortunately, that funky thing doesn't really matter :)
% bin2int 10ftny
can't use non-numeric string as operand of "|"
Booleans are more than just zeros and ones.
--
-Kaitzschu
s="TCL ";while true;do echo -en "\r$s";s=${s:1:${#s}}${s:0:1};sleep .1;done
I think you mean "fortunately" here ;-)
> % bin2int 10ftny
> can't use non-numeric string as operand of "|"
> Booleans are more than just zeros and ones.
>
In any case, passing a non binary string will generate an error. But
you prefer a consistent error message (not that the error thrown by
expr is not helpful) you can always change the check to the more
straightforward:
if {$bit == 0 || $bit == 1} {...