/* This is a demonstration program for the rootfinding subroutine 'bisect', given in Section 4.1. */ #include #include float fcn(float); float sign(float, float); void bisect(float(*f)(float), float, float, float, float *, int *); main() { float a, b, epsilon, root; int ier; while (1) { /* Input problem parameters */ printf("\n\n What are a,b,epsilon"); printf("\n to stop, let epsilon=0 : \n"); scanf("%f %f %f", &a, &b, &epsilon); if (epsilon == 0.0) return 0; /* Calculate root */ bisect(fcn, a ,b ,epsilon, &root, &ier); /* Print answers */ printf("\n\n a = %11.4e b = %11.4e epsilon = %9.3e", a, b, epsilon); printf("\n root = %14.7e ier = %1d", root, ier); } return 0; } float fcn(float x) { float result; result = x - exp(-x); return(result); } float sign(float a, float b) { if (b < 0.0) return(-fabs(a)); else return(fabs(a)); } void bisect(float(*f)(float), float a, float b, float eps, float *root, int *ier) { /* The program uses the bisection method to solve the equation f(x) = 0. The solution is to be in [a,b] and it is assumed that f(a)*f(b) <= 0. The solution is returned in root, and it is to be in error by at most eps. ier is an error indicator. If ier=0 on completion of the routine, then the solution has been computed satisfactorily. If ier=1, then f(a)*f(b) was greater than 0, contrary to assumption. */ const float zero = 0.0, one = 1.0, two = 2.0; float c, fa, fb, fc, sfa, sfb, sfc; /* Initialize */ fa = (*f)(a); fb = (*f)(b); sfa = sign(one, fa); sfb = sign(one, fb); if (sfa*sfb > 0.0) { /* The choice of a and b is in error */ *ier = 1; return; } /* Create a new value of c, the midpoint of [a,b] */ while (1) { c = (a + b)/two; if (fabs(b-c) <= eps) { /* c is an acceptable solution of f(x)=0 */ *root = c; *ier = 0; return; } /* The value of c was not sufficiently accurate. Begin a new iteration */ fc = (*f)(c); if (fc == zero) { /* c is an acceptable solution of f(x)=0 */ *root = c; *ier = 0; return; } sfc = sign(one, fc); if (sfb*sfc > zero) { /* The solution is in [a,c] */ b = c; sfb = sfc; } else { /* The solution is in [c,b] */ a = c; sfa = sfc; } } }