[Richard Suchenwirth] 2002-07-06 - Every string standing for a number in a positional value system (as opposed to e.g. [Roman numbers] or [Hebrew numbers]) has to be understood relative to its base. We're most familiar with base 10 (the decimal system), where e.g. 123 stands for 1*10^2 + 2*10^1 + 3*10^0 and in computery the bases 2 (binary), 8 (octal), and 16 (hexadecimal) are also fairly common, but any integer could function as a base as long as we have enough distinct digits. If you want to experiment with other bases, here are two routines that convert a number to and from a different base, up to 62 ([base64] uses a very different sequence of digits, so I didn't go that far) Note also that signs are preserved (unlike computery habit to have octals and hexadecimals as unsigned, resp. sign-extended). You could have that with base $myBase [format %u $number] Also, the C/Tcl markup of prefixing 0 to octals and 0x to hexadecimals is not created or recognized - how would e.g. a number to base 3 be marked? Like in Ada, 3#12021# ? So you have to keep track of number bases yourself. ---- [Converting numbers from arbitrary bases] is an earlier approach at the same topic. ---- proc base {base number} { set negative [regexp ^-(.+) $number -> number] ;# (1) set digits {0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z} set res {} while {$number} { set digit [expr {$number % $base}] set res [lindex $digits $digit]$res set number [expr {$number / $base}] } if $negative {set res -$res} set res } proc frombase {base number} { set digits {0 1 2 3 4 5 6 7 8 9 A B C D E F G H I J K L M N O P Q R S T U V W X Y Z a b c d e f g h i j k l m n o p q r s t u v w x y z} set negative [regexp ^-(.+) $number -> number] set res 0 foreach digit [split $number ""] { set decimalvalue [lsearch $digits $digit] if {$decimalvalue<0 || $decimalvalue >= $base} { error "bad digit $decimalvalue for base $base" } set res [expr {$res*$base + $decimalvalue}] } if $negative [set res -$res] set res } Examples: % base 7 1234 3412 % frombase 7 3412 1234 % base 16 255 FF One might use this to experiment with ''number palindromes'', where the sequence of digits is reverted: % base 19 42 24 % frombase 19 24 42 ---- # (1): In the [Tcl chatroom], [Michael Schlenker] reported: set negative [expr {$number != [set number [expr {abs($number)}]]}] is about five times faster if negative, and a bit faster if positive. ---- [Category Mathematics] - [Arts and crafts of Tcl-Tk programming]