A way to convert any arbitrary number to engineering notation [http://en.wikipedia.org/wiki/Engineering_notation] # eng - return engineering notation of any given number in a 2 element list as {num eng_unit} # pico nano micro milli 1 kilo Mega Giga Tera # use: eng eg. eng 123.456E6 Hz # First - scan to check if n is a number, if not then just return with input given {n u} proc eng {n u} { if ![scan $n %g res] {return [list $n {} $u]} if [expr $n>=1E-12 && $n<1E-9] {list [expr $n*1E12] p$u} \ elseif [expr $n>=1E-9 && $n<1E-6] {list [expr $n*1E9] n$u} \ elseif [expr $n>=1E-6 && $n<1E-3] {list [expr $n*1E6] u$u} \ elseif [expr $n>=1E-3 && $n<1] {list [expr $n*1E3] m$u} \ elseif [expr $n>=1 && $n<1E3] {list [format %g $n] $u} \ elseif [expr $n>=1E3 && $n<1E6] {list [expr $n/1E3] k$u} \ elseif [expr $n>=1E6 && $n<1E9] {list [expr $n/1E6] M$u} \ elseif [expr $n>=1E9 && $n<1E12] {list [expr $n/1E9] G$u} \ elseif [expr $n>=1E12 && $n<1E15] {list [expr $n/1E12] T$u} \ else {list [format %g $n] $u} } ### Example Output %eng 1.23456E-2 V 12.3456 mV %eng 209357.209857E5 Hz 20.9357209857 GHz %eng 0.012e-7 H 1.2 nH [CvK] (Dec 2006) - is there any way this could be simplified ? [Bryan Oakley] notes: that's a lot of unbraced expressions! ''[MJ] - even more so if you consider that if and elseif pass the first following argument to expr as well. Always [brace your expr-essions]''. For that matter, "if [expr ..." is a bit redundant. [AMG]: The rampant indenting was hurting my eyes, so I removed it. This version should be a bit easier to read. [MJ] - Try the following (with the additional benefit that it is easier to add more powers of 1000): proc eng {num u} { array set orders { -8 y -7 z -6 a -5 f -4 p -3 n -2 u -1 m 0 {} 1 k 2 M 3 G 4 T 5 P 6 E 7 Z 8 Y } set numInfo [split [format %e $num] e] set order [expr {[scan [lindex $numInfo 1] %d] / 3}] if {[catch {set orders($order)} prefix]} {return [list $num $u]} set num [expr {$num/pow(10,3*$order)}] return [list $num $prefix$u] } [CvK] - MJ, Thanks for your solution. It looks better and perhaps more readable. I agree that the nested "if [expr .." is redundant. Syntax highlighting helped with the aesthetics of indentation which is lost with the pre-formatting in this wiki. I tried your example but it gave a syntax error ... syntax error in expression "$num/(10.**(3*$order))": unexpected operator * [MJ] - That's what I get for testing under 8.5 only. In 8.5 ** is a new operator. Fixed above. BTW not only is "if [expr .." redundant, it is also slower and invokes ''triple'' substitution which can lead to very unexpected or even unsecure behaviour. Example: % set a 1 % set b {$a} % set c {$b} % if [expr $c] {puts "3 times is a charm :-)"} {puts "... or not"} 3 times a charm :-) % set a 0 % if [expr $c] {puts "3 times is a charm :-)"} {puts "... or not"} ... or not [CvK] - The speed difference as measured by ''[[clock clicks]]'' is about 5 fold. I measured an average of about 430 ''[[clock clicks]]'' for the "if..elseif" version, while MJ's "pow()..array-lookup" version measured about 80 ''[[clock clicks]]'', approximately 5 times faster. Not sure what units of time ''[[clock clicks]]'' returns, but the measure is a relative difference anyway. [NEM] - ''clock clicks'' returns a system-dependent value. You can use the [time] command for benchmarking. () 3 % time {eng 209357.209857E5 Hz } 1000 ; # ifelse version 222.984 microseconds per iteration () 5 % time {eng 209357.209857E5 Hz } 1000 ; # array lookup version 88.785 microseconds per iteration [aa] - After turning all the elseif [expr ...] {...} \ into elseif {...} {...} \ I found the two routines to be roughly equivalent in time taken. ---- BTW - what improvements does Tcl8.5 offer? ''See [Changes in Tcl/Tk 8.5]'' ---- [[ [Category Mathematics] ]]