#include <stdio.h>
#include <math.h>


static double bisect(double (*f)(double), double a, double b, double tolerance,
        unsigned int *steps, unsigned int max_steps, double approximation,
        int error_per_step)
{
    double c = INFINITY;

    for ( *steps = 1; *steps < max_steps; *steps += 1) {
        c = (a + b) / 2;

        if ( error_per_step )
            printf("step %2d error: %.3E (%3f%%)\n", *steps,
                fabs(approximation - c),
                100 * fabs(c - approximation) / approximation);

        if (f(c) == 0 || (b - a) / 2 < tolerance)
            return c;

        if (signbit(f(c)) == signbit(f(a)))
            a = c;
        else
            b = c;
    }

    return c;
}


#ifdef MAIN_bisection

static inline double f(double x) { return x * sin(x) - 1.0; }

int main(void)
{
    double approximation = 1.11415714087193008730052518;
    unsigned int steps;

    bisect(&f, 0.0, 2.0, 10e-12, &steps, 100, approximation, 0);

    printf("bisection of x * sin(x) - 1 for x in [%.1f, %.1f] in %d steps.\n",
           0.0, 2.0, steps);

    return 0;
}

#endif
