| functions/root-fn-ptr-2.c - En version uden dereferencing og address operator på funktionerne. | Lektion 6 - slide 14 : 21 Program 3 |
#include <stdio.h>
#include <stdlib.h>
#include <math.h>
double pol1 (double x){
/* (x - 5.0) * (x - 3.0) * (x + 7.0) */
return (x*x*x - x*x - 41.0 * x + 105.0);
}
double pol2 (double x){
return (x*x - 2.0);
}
int sameSign(double x, double y){
return (x > 0 && y > 0) || (x < 0 && y < 0);
}
double middleOf(double x, double y){
return x + (y - x)/2;
}
int isSmallNumber(double x){
return (fabs(x) < 0.0000001);
}
/* Precondition: The sign of f(l) and f(u) are different */
double findRootBetween(double (*f)(double), double l, double u){
while (!isSmallNumber((*f)(middleOf(l,u)))){
if(sameSign((*f)(middleOf(l,u)), (*f)(u)))
u = middleOf(l,u);
else
l = middleOf(l,u);
}
return middleOf(l,u);
}
int main (void){
double x, y;
int numbers;
int function_selection;
double (*fn)(double); //fn is a pointer to a function: double -> double
int done = 0;
do{
/* Select function: */
printf("Select function:\n");
printf("1: x*x*x - x*x - 41.0 * x + 105.0\n");
printf("2: x*x - 2.0\n");
printf("3: sin\n");
printf("4: EXIT\n");
scanf("%d", &function_selection);
switch(function_selection){
case 1:
fn = pol1; break;
case 2:
fn = pol2; break;
case 3:
fn = sin; break;
default:
done = 1;
}
/* Find a root in selected function: */
if (!done){
printf("%s","Find a ROOT between which numbers: ");
numbers = scanf("%lf%lf", &x, &y);
if (numbers == 2 && !sameSign(fn(x),fn(y))){
double solution = findRootBetween( fn , x ,y);
printf("\nThere is a root in %lf\n\n", solution);
}
else if (numbers == 2 && sameSign(fn(x),fn(y)))
printf("\nf must have different signs in %lf and %lf\n\n",
x, y);
else if (numbers != 2)
done = 1;
}
}
while (!done);
return 0;
}