Newsgroup: it.comp.lang.c
Titolo: problemino di calcolo numerico

Salve, mi presento , perchè d'ora innanzi penso che vi "frequenterò" spesso ;
Sono Paolo, sono mortalmente attratto dal nostro caro linguaggio di
programmazione, è potente, potentissimo, solo che ... Lo conosco ancora poco e
sto imparnadolo da solo;  a momento ,dovrò  presentare delle tesine di calcolo
numerico all'università (non sono informatico) e ho scelto di mettermi a
studiare il C piutttosto che adoperare a questo scopo il tristissimo FORTRAN;
Le mie basi di informatica sono al momento limitate a quest'ultimo e al Pascal;
Tanto per incominciare: ho sempre avuto difficoltà con il passaggio di
variabili  per indirizzo oper valore dal programma chiamante, e vorrei
risolvere una volta per tutte questo dubbio;
Includo di seguito un programmino che dovrebbe trovare lo zero una funzione
in un certo intervallo che acquisisce da tastiera :
ma non è questo che chiedo, il programma è cewrtamente da raffinare, piutttosto:
sbaglio qualcosa nel passaggio di parametri perchè mi restituisce sempre lo
zero  come x=0
# include <stdio.h>
# include <math.h>
int passi;
double a,b,y,med,soluzione;
 double f(double); 
 double bisezione(double,double); 
       int main()
                {
                  printf("\n Inserisci a \n");
                  scanf("%f",&a);
                  printf("\n Inserisci b  \n");
                  scanf("%f",&b);
                  bisezione(a,b);
                  printf("\n Lo zero è approssimativamente in x=");
                  printf("%d",soluzione);
                  printf("\n\n\n"); 
                 }
          double  bisezione(double a,double b)  
                      {
                       while ((f(a))*(f(b))<0)  {
                                           med=((b-a)/2);
                                           if (f(a)*f(med)<0) {
                                                              b=med;
                                                              break;
                                                              }
                                           else {
                                                if(f(a)*f(med)>0){
                                                             a=med;
                                                             break;}
                                                else soluzione=med;
                                                return soluzione;              
    /*    serve il return?  */
                                                   }
                                                             };
                      };
/* questa è la generica f(x) , può essere variata per testare il programma   */
       double f(double x)
                       {
                        y=(log(x));
                       };
Ciao a tutti e grazie per l'attenzione;
Paolo 8-)

you wrote:
double  bisezione(double a,double b)  
{
        while ( f(a)*f(b) < 0 )  
        {
              med = (b-a)/2 ;
              if ( f(a)*f(med) < 0 ) 
              {
                 b = med ;
              }
              else 
              if ( f(a)*f(med) > 0 )
              {
                 a = med ;
              }
              else return med ;
        }  
}
funzionera' ?

                        };
Uno degli errori è sicuramente qui: manca il return. La dovresti
scrivere come
double f(double x)
{
    return log(x);
};
Quindi la variabile y non ti serve neanche.
EMG

                        };
la variabile globale y non serve devi fare return per restituire il valore
della funzione... cmq se tu volevi usare lo stesso la varibile y dovevi
confrontare lei nella condizione del while e quindi sarebbe risultata errata
la condizione che avevi messo nel ciclo.
Questa è una versione con tutte le correzioni che ti ho segnalato...
naturalmente mancano controlli in lettura, si suppone che f(a) e f(b)
abbiano segni opposti e siano entrambi diversi da 0, ecc...
#include <stdio.h>
#include <math.h>
#define range 0.0001
double f(double x){
  return log(x);
}
double bisezione(double a,double b){
double med;
  while ( (f(a)*f(b)<0) && (b-a>range) ) {
    med=((b+a)/2);
    if ( f(a)*f(med)<0 ) {
      b=med;
    }
    else {
      if( f(a)*f(med)>0 ){
        a=med;
      }
      else{           /*cioè se f(a)*f(med)==0 e hai già trovato la
soluzione*/
        return med;
      }
    }
  }
  return med;
}
int main(){
  double a,b,soluzione;
  printf("\nInserisci a\n");
  scanf("%lf",&a);
  printf("\nInserisci b\n");
  scanf("%lf",&b);
  soluzione=bisezione(a,b);  /*ci si poteva risparmiare anche la variabile
soluzione, ma forse così ti è più chiaro*/
  printf("\nLo zero è approssimativamente in x=%f \n\n\n",soluzione);
  return 0;
}
--
________________________________
per rispondermi iliasba(at)
tin.it
bye Brain

Questa è una versione con tutte le correzioni che ti ho segnalato...
Davvero impagabile ... 8-))
Grazie , bye Paolo 

    return log(x);
....
Ancora   Grazie
bye Paolo

 scanf()?
%c A single unsigned character
%d A signed decimal integer
%i  A signed decimal integer
%e A floating point variable (exponent)
%E A floating point variable (exponent)
%f  A floating point variable
%F A floating point variable
%g Allows system to choose either
%e or
%f
%G Allows system to choose either
%E or
%F
%hd A signed short integer
%hi  A signed short integer
%ho An unsigned short integer (octal)
%hn  A short argument
%hu  An unsigned short integer
%hx  An unsigned short integer (hexadecimal lower case)
%hX An unsigned short integer (hexadecimal upper case)
%ld  A signed long integer
%le  A double precision variable (exponent)
%lf   A double precision variable
%lg   Allows system to choose either
%le or
%lf
%li  A signed long integer
%ln  A long argument
%lo An unsigned long integer (octal)
%lu An unsigned long integer
%lx An unsigned long integer (hexadecimal lower case)
%lX An unsigned long integer (hexadecimal lower case)
%lE A double precision variable (exponent)
%Le A long double precision variable (exponent)
%LE A long double precision variable (exponent)
%lF A double precision variable
%Lf A long double precision variable
%LF A long double precision variable
%Lg Allows system to choose either
%Le or
%Lf
%lG Allows system to choose either
%lE or
%lF
%LG Allows system to choose either
%LE or
%LF
%n The number of characters written so far by printf
%p A generic pointer (and its address)
%o An unsigned integer (octal)
%s A pointer to a character string
%u An unsigned decimal integer
%x An unsigned hexadecimal (lower case)
%X An unsigned hexadecimal (upper case)
%% The % sign
#e Decimal point appears even when not needed.
#f Decimal point appears even when not needed.
#g Decimal point appears even when not needed.
#x Hexadecimal with ox prefix.
EMG

 b+-----+-----+-----med-----+-----+-----+a
Salve, vorrei aggiungere:
1- la "metà" (= il punto medio) di un intervallo [a,b] di numeri reali,
è il punto di coordinata (b+a)/2, 
non (b-a)/2, quest'ultima è invece la semilunghezza dell'intervallo. A
te serve il punto medio, l'algoritmo è un'applicazione del teorema del
passaggio per lo zero delle funzioni continue in una variabile reale.
Invece (b-a)/2 può benissimo essere esterno ad [a,b].
2- bisezione() funziona solo se nell'intervallo [a,b] iniziale, la
funzione passa per lo zero un numero dispari di volte (quindi non va
bene se non c'è nessuna soluzione in [a,b], oppure se ce ne sono 2 e
così via). Altrimenti si incasina, perchè il corpo del while non viene
eseguito e viene ritornato un valore indefinito. 
ciao.

Enrico Maria Giordano wrote:
Grazie mi mancava una raccolta completa :)
Ivan Molella