// Finding a Function Root Using the Bisection Method
// Finds roots of the equations
// g(x) = 0 and h(x) = 0
// on a specified interval [x_left, x_right] using the bisection method.
#include <stdio.h>
#include <math.h>
#define FALSE 0
#define TRUE 1
#define NO_ROOT -99999.0
// equation #1
double
g(double x)
{
return (5 * pow(x, 3.0) - 2 * pow(x, 2.0) + 3);
}
// equation #2
double
h(double x)
{
return (pow(x, 4.0) - 3 * pow(x, 2.0) - 8);
}
// Implements the bisection method for finding a root of a function f.
// Returns a root if signs of fp(x_left) and fp(x_right) are different.
// Otherwise returns NO_ROOT.
double
bisect(double x_left, /* input - endpoints of interval in */
double x_right, /* which to look for a root */
double epsilon, /* input - error tolerance */
double f(double farg)) /* input - the function */
{
double x_mid, /* midpoint of interval */
f_left, /* f(x_left) */
f_mid, /* f(x_mid) */
f_right; /* f(x_right) */
int root_found; /* flag to indicate whether root is found */
/* Computes function values at initial endpoints of interval */
f_left = f(x_left); f_right = f(x_right);
/* If no change of sign occurs on the interval there is not a
unique root. Exit function and return NO_ROOT */
if (f_left * f_right > 0) { /* same sign */
printf("\nMay be no root in [%.7lf, %.7lf]", x_left, x_right);
return (NO_ROOT);
}
/* Searches as long as interval size is large enough
and no root has been found */
root_found = FALSE; /* no root found yet */
while (fabs(x_right - x_left) > epsilon && !root_found)
{
/* Computes midpoint and function value at midpoint */
x_mid = (x_left + x_right) / 2.0;
f_mid = f(x_mid);
if (f_mid == 0.0) { /* Here's the root */
root_found = TRUE;
} else if (f_left * f_mid < 0.0) {/* Root in [x_left,x_mid]*/
x_right = x_mid;
} else { /* Root in [x_mid,x_right]*/
x_left = x_mid;
}
/* Trace loop execution - print root location or new interval */
if (root_found)
printf("\nRoot found at x = %.7lf, midpoint of [%.7lf, %.7lf]",
x_mid, x_left, x_right);
else
printf("\nNew interval is [%.7lf, %.7lf]",
x_left, x_right);
}
/* If there is a root, it is the midpoint of [x_left, x_right] */
return ((x_left + x_right) / 2.0);
}
int
main(void)
{
double x_left, x_right, /* left, right endpoints of interval */
epsilon, /* error tolerance */
root;
/* Get endpoints and error tolerance from user */
printf("Enter interval endpoints > ");
scanf("%lf%lf", &x_left, &x_right);
printf("Enter tolerance > ");
scanf("%lf", &epsilon);
/* Use bisect function to look for roots of g and h */
printf("\n\nFunction g");
root = bisect(x_left, x_right, epsilon, g);
if (root != NO_ROOT)
printf("\n g(%.7f) = %e\n", root, g(root));
printf("\n\nFunction h");
root = bisect(x_left, x_right, epsilon, h);
if (root != NO_ROOT)
printf("\n h(%.7f) = %e\n", root, h(root));
return (0);
}
Enter interval endpoints > -1.0 1.0
Enter tolerance > 0.001
Function g
New interval is [-1.0000000, 0.0000000]
New interval is [-1.0000000, -0.5000000]
New interval is [-0.7500000, -0.5000000]
New interval is [-0.7500000, -0.6250000]
New interval is [-0.7500000, -0.6875000]
New interval is [-0.7500000, -0.7187500]
New interval is [-0.7343750, -0.7187500]
New interval is [-0.7343750, -0.7265625]
New interval is [-0.7304688, -0.7265625]
New interval is [-0.7304688, -0.7285156]
New interval is [-0.7294922, -0.7285156]
g(-0.7290039) = -2.697494e-05
Function h
May be no root in [-1.0000000, 1.0000000]