[RS] Tcl's [expr] has logarithm to base e built-in: % expr exp(1) ;# Euler's number, or e for short 2.71828182846 8 % expr log(exp(1)) 1.0 Logarithms to most any other base can be had by division -- e.g for log10 of 1000: % expr log(1000)/log(10) 3.0 ---- [Feynman] apparently is in the domain literature for numerical analysis of an algorithm which computes the logarithm of a number between 1 and 2. Any such number is a unique product of factors of the form (1 + 2 ** -k) for integral k. Logarithms of all such factors fit in a table of modest size. Determination of the sequence of k-s can be done with shifts and subtracts. Here's a [Tcl] coding that illustrates the algorithm: ... See [math::bigfloat]::log for another algorithm. (with arbitrary precision) It uses this development: log(1+x)=x + x^2/2 + x^3/3 ... and does not require sqrt() to be present. It only needs arithmetics. ====== proc logarithm {x} { set eps 1e-[set ::tcl_precision] if {$x<=-1} {error "logarithm requires a positive argument"} set log $x set pow [expr {-$x*$x}] set i 2 set add [expr {$pow/$i}] while {abs($add)>$eps*abs($log)} { set log [expr {$log+$add}] incr i set pow [expr {-$pow*$x}] set add [expr {$pow/$i}] } incr i -2 #puts "$i iterations" return $log } proc log {x} { set doubles 0 if {$x<=0} {error "logarithm requires a positive argument"} if {$x<1} { while {$x<=0.5} { # iterate : x=x*2 until 1/2=2} { # iterate : x=x/2 until 1$eps*abs($system)} { puts "my log $x : $my" puts "system log($x) : $system" error "$x runs odd" } return $my } ====== -- [Sarnold] ---- [GS] (060114) Until we have the solution for above, here is an algorithm which computes the logarithm of a number between 0 and 1. ====== # Description: Log evaluation between 0 and 1 with a recursion formula # # / 2*u(i) \ # u(i+1) = u(i)*sqrt|-----------------| # \ u(i) + u(i-1) / # Arguments: # . x : the value to be computed # Results: # . y: the value of log(x) # . n: then number of iterations proc Log01 { x } { if {$x <= 0 || $x > 1} return set eps .000000001 set n 0 set y 0 set du 10000 set x2 [expr {$x*$x}] set u0 [expr {($x2 - 1.0/$x2)/4}] set u1 [expr {($x-1.0/$x)/2}] while {$du > $eps} { set u2 [expr {$u1*sqrt(2*$u1/($u1+$u0))}] set y $u2 incr n set du [expr {abs($u2-$u1)}] set u0 $u1 set u1 $u2 } return [list $y $n] } # Test for {set i 2} {$i < 10} {incr i} { set x [expr {1.0/$i}] set r [Log01 $x] puts "Log($x) = [format "%.8f" [lindex $r 0]] in [lindex $r 1] iterations" } ====== Test results: Log(0.5) = -0.69314718 in 14 iterations Log(0.333333333333) = -1.09861229 in 15 iterations Log(0.25) = -1.38629436 in 16 iterations Log(0.2) = -1.60943791 in 16 iterations Log(0.166666666667) = -1.79175947 in 16 iterations Log(0.142857142857) = -1.94591015 in 16 iterations Log(0.125) = -2.07944154 in 17 iterations Log(0.111111111111) = -2.19722458 in 17 iterations <> Mathematics