// Bisection method for g(z) = 0.  This version simply assumes that
//   initial guesses for a z-range spanning the root have been provided.

#include <iostream>
#include <cmath>
using namespace std;

#define real double
#define TOL 0.0001

real g(real z)				// the equation to solve
{
    return exp(z) - 2.0;
}

int find_root(real zl, real zr)		// bisection to tolerance TOL
{
    int n = 0;
    while (fabs(zl - zr) > TOL) {
	real zm = 0.5*(zl + zr);
	if (g(zm)*g(zl) > 0)
	    zl = zm;
	else
	    zr = zm;
	n++;
    }
    return n;
}

real secant(real zl, real zr)		// one secant iteration
{
    real zs = zl + (zr - zl) * (-g(zl)) / (g(zr) - g(zl));

    if (g(zs)*g(zl) > 0)
	zl = zs;
    else
	zr = zs;

    return zs;
}

main()
{
    real zl, zr;
    int n;

    zl = 0;				// initial range
    zr = 10;

    n = find_root(zl, zr);

    printf("Root lies in range (%f, %f) after %d iterations.\n", zl, zr, n);
    printf("Function value at midpoint = %g\n", g(0.5*(zl+zr)));
    printf("Function value after 1 secant iteration  = %g\n",
	   g(secant(zl, zr)));
    printf("Function value after 2 secant iterations = %g\n",
	   g(secant(zl, zr)));
}

