Math on binary strings

A recent query on comp.lang.tcl asked how one might find the sum of two binary numbers, without converting them to decimal returning the result as binary.

Glen Jackson wrote the following code:

if {[string match 8.4* [package require Tcl]]} {
package require struct::list
interp alias {} list_reverse {} struct::list reverse
} else {
interp alias {} list_reverse {} lreverse
}

proc add_binary_strings {n1 n2} {
set carry 0
foreach d1 [list_reverse [split \$n1 ""]] \
d2 [list_reverse [split \$n2 ""]] \
{
if {\$d1 eq ""} {set d1 0}
if {\$d2 eq ""} {set d2 0}
switch -exact [set sum [expr {\$d1 + \$d2 + \$carry}]] {
0 -
1 { set carry 0 }
2 { set sum 0; set carry 1 }
3 { set sum 1; set carry 1 }
}
}
return [string trimleft [join [list_reverse \$answer] ""] 0]
}

set n1 100010111
set n2   1011011

puts "\$n1 + \$n2 = [add_binary_strings \$n1 \$n2]"

Lars H: Ah, but it's slightly neater to do it without expr:

proc add_binary_strings {n1 n2} {
set sum {}
set carry 0
foreach d1 [list_reverse [split \$n1 ""]] d2 [list_reverse [split \$n2 ""]] {
switch -- [string map {0 ""} "\$d1\$d2\$carry"] {
""  { lappend sum 0; set carry 0}
1   { lappend sum 1; set carry 0}
11  { lappend sum 0; set carry 1}
111 { lappend sum 1; set carry 1}
}
}
lappend sum \$carry
return [string trimleft [join [list_reverse \$sum] ""] 0]
}

vh 17 Apr 2017 - How can I manipulate the output so that I can use the format %d \$output command to return the decimal value? This command assumes that the output string is already a decimal value. I was trying to use this function to help me with the +1 part of the 2's complement calculation. Am I doing to much work? Is there another, easier way? (Ok, that was probably a dumb question - I've added a bin2dec function to by library...)

arjen (18 april 2017) Better ask this type of things on comp.lang.tcl than in the Wiki - your question will be more visible there.