Seldom Seen Smith's Nightmare: \(e^x\)

I recently read "The Monkey Wrench Gang" by Edward Abbey (a 1975 novel about environmental activism and industrial sabotage), and there's a scene where a character known as Seldom Seen Smith has a nightmare. While trying to break into a dam's control room a robot captures him, describes the assembly programming interface for a simple computer, and threatens to electrocute him unless he can implement \(e^x\) as an infinite series within 0.000015ms.

It took me more than 0.000015ms to simulate that machine in Python and write the program, but it was a fun diversion.

mwg-exp.py:

#!/bin/env python3

# Evaluate exp(x) with an infinite series, as requested by the
# Operator in Seldom Seen Smith's nightmare in The Monkey Wrench Gang
# by Edward Abbey.  The Operator describes the assembly language for a
# simple computer which is simulated here.  It took me more than
# 0.000015 milliseconds to write this.

import math

x = 1.0                         # Input argument
expected_result = math.exp(x)

print(f"Input: {x}")
print(f"Expecting: {expected_result}")

w = x                           # Working register
s = [0.0] * 6                   # Storage locations

s[0] = 2.0                      # Iteration counter
s[1] = 1.0                      # Factorial
s[2] = 1.0                      # Partial sum
s[3] = x                        # Powers of x
s[4] = 1.0                      # Unity (constant)
s[5] = x                        # Input argument (constant)

# Functions to simulate the machine's op-codes.
def T(n):                       # Store working register.
    global w, s
    s[n] = w

def B(n):                       # Load working register.
    global w, s
    w = s[n]

def add(n):
    global w, s
    w = w + s[n]

def sub(n):
    global w, s
    w = w - s[n]

def mul(n):
    global w, s
    w = w * s[n]

def div(n):
    global w, s
    w = w / s[n]

def Z():
    exit(0)                     # End program.

print(w, s)

add(4)                          # Add 1 to x.
T(2)                            # Save the result.
B(1)                            # Load factorial.
mul(0)                          # Multiply by iteration count.
T(1)                            # Save result.
B(3)                            # Load power of x.
mul(5)                          # Multiply by x.
T(3)                            # Save result.
div(1)                          # Divide by factorial.
add(2)                          # Add to partial sum.
T(2)                            # Save result.

print(w, s)

for i in range(0,15):
    B(0)                        # Increment iteration counter.
    add(4)
    T(0)
    B(1)                        # Update factorial.
    mul(0)
    T(1)
    B(3)                        # Update power of x (x^n).
    mul(5)
    T(3)
    div(1)                      # Divide by factorial.
    add(2)                      # Add to partial sum.
    T(2)                        # Save result.

    print(w, expected_result, w - expected_result, s)

Z()

This is a pretty straightforward implementation of this expression for \(e^x\) (copied from Wikipedia):

\[e^x = \sum_{n=0}^\infty {x^n \over n!} = 1 + x + \frac{x^2}{2!} + \frac{x^3}{3!} + \frac{x^4}{4!} + \cdots\]

Jack Crenshaw's book Math Toolkit for Real-Time Programming has a lot to say about improved methods for calculating exponents and other functions. I recommend it.

© Copyright 2023, Remington Furman

blog@remcycles.net

@remcycles@subdued.social