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 answer [list] 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 } } lappend answer $sum } lappend answer $carry 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.