/** * expt.c * Code for efficient exponentiation. */ // +---------+------------------------------------------------------- // | Headers | // +---------+ #include "expt.h" // +---------------+------------------------------------------------- // | Local Helpers | // +---------------+ /** * Compute x^n for non-negative n. */ double exptkernel (double x, int n) { if (0 == n) { return 1.0; } else if (0 == (n % 2)) { return exptkernel (x*x, n/2); } else { return x * exptkernel (x*x, (n-1)/2); } } // exptkernel /** * Compute x^n for non-negative n */ double expt2kernel (double X, int N) { double result = 1.0; double x = X; double n = N; // Invariant: result * x^n = X^N while (n > 0) { if (0 == (n % 2)) { x = x*2; n = n/2; } else { result = result*x; n = n-1; } } // while return result; } // expt2kernel // +--------------------+-------------------------------------------- // | Exported Functions | // +--------------------+ double exptd (double x, int n) { if (n < 0) { return 1.0 / exptkernel (x, -n); } else { return exptkernel (x, n); } } // exptd double expt2 (double x, int n) { if (n < 0) { return 1.0 / expt2kernel (x, -n); } else { return expt2kernel (x, n); } } // expt2