#include #include #include double fun1(double x); double der1(double x); double fun2(double x); double der2(double x); int main(){ double eps=1.,xlast=0.,xnew=0.,delta=10000.; double (*f)(double), (*d)(double); /* Definizione di due puntatori a funzioni di variabile double che restituiscono valori double; ***ATTENZIONE*** la prima parentesi e' essenziale, la definizione double *f(double) definisce un puntatore ad una funzione di variabile double che restituisce un puntatore a double !!! */ int scelta=0,i=0; /* Questa struttura puo' eventualmente essere semplificata duplicando il codice per f1 ed f2...ma questo metodo e' molto piu' elegante, non trovate ? */ printf("Di quale funzione vuoi trovare lo zero ?\n"); printf("[0]\t x - 5 ln(x)\n"); printf("[1]\t 1/x - (1-exp(-x))\n"); scanf("%d",&scelta); switch(scelta){ case 0 : printf("Hai scelto la funzione x - 5 ln(x)\n"); /* Qui si assegnano i puntatori a funzione "generici" f e d alla funzone scelta e alla sua derivata. */ f = &fun1; d = &der1; break; case 1 : printf("Hai scelto la funzione 1/x - (1-exp(-x))\n"); /* Qui si assegnano i puntatori a funzione "generici" f e d alla funzone scelta e alla sua derivata. */ f = &fun2; d = &der2; break; } /* Chiede la stima iniziale (del tutto arbitraria, ma attenzione al dominio! ) dello zero. Controlla che la derivata non si annulli nel punto chiedendo che il suo valore assoluto sia maggiore di un numero "molto piccolo" */ do{ if(i>0) fprintf(stderr,"La derivata della funzione scelta si annulla in questo punto!\n"); printf("Inserisci la stima iniziale per lo zero\n"); scanf("%lf",&xlast); i++; } while(fabs(d(xlast))<1.e-12); printf("Inserisci la precisione richiesta\n"); scanf("%lf",&eps); /* Questo e' il metodo di Newton vero e proprio */ while(delta>eps*fabs(xlast)){ xnew = xlast - f(xlast)/d(xlast); printf("%lf \n",xnew); delta = fabs(xnew-xlast); xlast = xnew; } printf("Lo zero cercato e' %.12lf\n",xnew); printf("Ricorda che puoi cercare altri zeri della funzione inserendo diverse stime iniziali\n"); return (0); } double fun1(double x){ return(x - 5*log(x)); } double der1(double x){ return(1 - 5/x); } double fun2(double x){ return(1/x - (1-exp(-x))); } double der2(double x){ return(-1./(x*x)-exp(-x)); }