## What if you do not have exp()?

Arjen Markus (14 july 2008) Recently, on the Tclers' chat, someone had a problem with the [expr] command as in their installation tclsh apparently did not have any math functions. While it was easy enough to provide an alternative for sqrt() (see Square root for instance), a function like exp() presents more difficulties. Or does it?

Not really: Abramowitz and Stegun come to the rescue, along with a few properties of the exponential function. The result is remarkably accurate. I leave the log, sin, cos, tan, acos, asin and atan functions as an exercise.

```# approx_exp.tcl --
#     An approximation of the exponential function
#     (Based on Abramowicz and Stegun)
#

# exp --
#     Compute an approximation of exp(x)
#
# Arguments:
#     x      Value for which to evaluate the exponential function
#
# Returns:
#     Approximation of exp(x)
#
proc exp {x} {
set ln2   0.693147805599543
set E     2.718281828459045
set sqrtE 1.6487212707001282

#
# As the valid range for the basic approximation is 0 - ln(2),
# reduce the argument
#
set factor    1.0
if { \$x > 0.0 } {
set reciproke 1
} else {
set reciproke 0
set x [expr {-\$x}]
}
while { \$x > 1.0 } {
set x [expr {\$x - 1.0}]
set factor [expr {\$factor * \$E}]
}

if { \$x > \$ln2 } {
set x [expr {\$x - 0.5}]
set factor [expr {\$factor * \$sqrtE}]
}

#puts "Reduced x: \$x \$factor"
set exp [expr {(1.0 + \$x * (-0.9998684 + \$x * (0.4982926 +
+ \$x * (-0.1595332 + \$x * 0.0293641))))}]

if { \$reciproke } {
set exp [expr {\$factor / \$exp}]
} else {
set exp [expr {\$factor * \$exp}]
}
return \$exp
}

# main --
#     Put it to the test
#
puts [format "%12s %12s%12s%12s%12s" X "exp x" "exp(x)" "abs. diff" "rel. diff"]
foreach x {0.1 0.2 0.5 1.3 2.4 4.05 -0.1 -0.2 -0.5 1.3 2.4 4.05} {
set exp1 [exp \$x]
set exp2 [expr {exp(\$x)}]
puts [format "%12.4f:%12.4f%12.4f%12.4e%12.4e" \$x \$exp1 \$exp2 [expr {\$exp1-\$exp2}] \
[expr {\$exp1/\$exp2-1.0}]]
}```

 Category Mathematics