28/12/09 10:04
matteog
salvè,devo svolgere un esercizio per le vacanze in cui dati in ingresso a e b, ovvero il valore massimo e minimo di un intervallo e n il numero di volte che devo ripetere l'azione su tale intervallo.Mediante il metodo di bisezione devo trovare i valori per cui la funzione sen(x) si annulla :
Ultima modifica effettuata da matteog 28/12/09 22:25
aaa
28/12/09 12:39
TheKaneB
non ho studiato approfonditamente il tuo codice ma ho notato subito un grossolano errore.
Il metodo di bisezione è una tecnica di approssimazione, in quanto tale non troverà mai il valore esatto della tua incognita (in questo caso l'angolo che azzera il seno). Aggiungi inoltre il fatto che i calcoli in floating point sono soggetti a numerosi arrotondamenti ed approssimazioni, quindi il classico "sen( x ) == 0" non funzionerà MAI!
devi invece predisporre un intervallo con un range di errore ammissibile ragionevole.
ad esempio potremmo considerare accettabile un valore compreso tra -0.001 e +0.001
in questo caso bisognerà confrontare sen( x ) con un range, quindi sarebbe, in termini matematici:
-0.001 < sen(x) < +0.001
da cui
|sen(x)| < 0.001
quindi il test da effettuare sarebbe:
if (abs(sen(x)) < 0.001){ ... }
Puoi anche parametrizzare il range usando una variabile al posto di 0.001.
Ovviamente, nel test di maggiore/minore dovrai usare al posto dello zero, lo stesso valore 0.001 (nel caso di "maggiore di"
e -0.001 (nel caso di "minore di"
.
Ultima modifica effettuata da TheKaneB 28/12/09 12:41
aaa
28/12/09 13:56
La ricerca per bisezione è impostata in modo errato.
Bisogna assicurarsi sempre che agli estremi vi siano risultati opposti.
Quì ho riportato il programma:
#include "stdafx.h"
#include <iostream>
#include <math.h>
using namespace std;
int main()
{
double a,b,c,errore=0.00005;
double sena,senb,senc;
int n;
cout<<"inserisci a:"<<endl;//inserimento degli intervalli:[a,b] e del numero di volte che devo eseguire la bisezione
cin>>a;
cout<<"inserisci b:"<<endl;
cin>>b;
cout<<"inserisci n:"<<endl;
cin>>n;
sena=sin(a);
senb=sin(b);
for(int i=0;i<n;i++)
{
c=(a+b)/2.0;
senc=sin(c);
if (i==n-1) cout<<"Limite di "<<n<<" iterazioni superato!\na= "<<a<<" b= "<<b<<endl;
if (sena*senb>0)
{
cout<<"\nNon esistono radici in questo intervallo!\n\n";
i=n; // uscita dal ciclo.
}
if(fabs(senc)<errore)
{
cout<<"la radice cercata è="<<c<<endl;
i=n; // uscita dal ciclo.
}
else
{
if(sena*senc<0)
{
b=c;
senb=senc;
}
else
{
a=c;
sena=senc;
}
}
}
system("pause"
;
return 0;
}
Ultima modifica effettuata da 28/12/09 13:59
28/12/09 15:08
matteog
vi ringrazio molto finalmente il programma funziona siete grandi!grazie mille
aaa
28/12/09 15:13
matteog
mi sono accprto dui una cosa però:
se io inserisco
due valori grandi tipo -10 e 20 con n=100 perchè non stampa tt i puno in cui sen x và a 0 in quel periodo?
aaa
28/12/09 16:17
Ricordati che:
1° Il metodo della bisezione, funziona solo nel caso vi sia una sola radice nell' intervallo dato.
2° La funzione sin(x) restituisce il seno dell' angolo x espresso in redianti.
Per la conversione:
radianti=gradi sessagesimali*0.0174533
gradi sessagesimali=radianti*57.2958
Buone feste!
Ultima modifica effettuata da 28/12/09 16:19
28/12/09 16:20
matteog
daccordo un ultima cosa per far si che nel caso in cui vengano inseriti -4 -2 e n=100 come posso fare per far si che mi restituisca un valore più preciso rispetto al pgreco perchè qui lo arrotonda subito a 3,1416 e si ferma me lo sapete dire?
aaa
28/12/09 16:36
Riduci il valore della variabile errore, aumenta il numero di cicli.
Eventualmente aumenta le cifre da visualizzare, con setprecision(n).
Per utilizzare questa funzione devi incluudere la libreria <iomanip>
Es.:
int main()
{
....
double c=4.9874;
cout<<setprecision(3)<<c;
...
}
Visualizzerà 4.99