PDA

Visualizza la versione completa : [C++] Programma risolvi equazioni


Bellerofonte90
11-01-2008, 17:25
Questo un programma che risolve le equazioni di qualunque grado con il metodo di bisezione, cio ogni volta si prende un intervallo a-b, si prende il numero che si trova in mezzo tra a e b chiamato m e si controlla se sostituendo all'equazione la x con la a, poi con la m e poi con la b, si vedono i risultati, e per esempio se i risultati sono

a negativo, m negativo e b positivo

significa che il risultato si trova tra m e b, si scarta l'intervallo a-m e la m si trasforma nella nuova in a e quindi si ricomincia da capo trovando il numero che si trova in mezzo, risostituendo etc...

questo fino a che b-a non minore della nostra precisione che immettiamo all'inizio (es. 0.0001 cio 4 cifre dopo la virgola)

questa la spiegazione del metodo di wikipedia
http://it.wikipedia.org/wiki/Metodo_della_bisezione

ecco il codice


#include "stdafx.h"
#include <iostream>
#include <cmath>
using namespace std;

long double equazione (long double);
void trova (long double[],int &);

int main()
{
long double radici[20];
int quante;
long double a,b,m,pre;
long double ris[3];

cout<<"Decidi la precisione \n";
cin>>pre;

trova(radici,quante);

cout<<quante;
for(int i=0;i<=quante;i++)
{
a=radici[i]+1;
b=radici[i]-1;
m=(a+b)/2;
do
{
ris[0]=equazione(a);
ris[1]=equazione(m);
ris[2]=equazione(b);
if(ris[1]<0)
a=m;
else
b=m;
if(b-a<pre)
break;
if(fabs(a)>fabs(b))
{
cout<<"Una radice e' "<<b<<endl;
}
else
{
cout<<"Una radice e' "<<a<<endl;
}

}while(1);

}

return 0;
}

long double equazione (long double x)
{
long double ris;
//parte modificabile
ris=2*pow(sin(x),4)-3*pow(sin(x),2)+1;

return ris;
}

void trova (long double ris[],int & iter)
{
iter=0;
long double temp1,temp2;

temp1=equazione(-1000);

for(int i=-1000;i<1000;i++)
{
temp2=equazione(i+1);
if((temp1<0 && temp2>0) || (temp1>0 && temp2<0))
{
ris[iter]=i;
iter++;
}
if(temp2==0)
{
cout<<"Una radice e' "<<i+1<<endl;
}
temp1=temp2;
}
return;
}


il problema che nel runtime mi dice che c' un accesso violento ad una locazione di memoria... ma errori sintattici nessuno e credo pure errori logici, dategli un'occhiata, il prof di matematica ce li ha lasciati oggi da fare e entro domani li vuole fatti!!!!!

Grazie a tutti per l'aiuto che mi state dando.

pallinopinco
11-01-2008, 17:39
mi dice che c' un accesso violento ad una locazione di memoria


Questa semplicemente stupenda... :)

Ho iniziato a vedere il tuo codice dalla fine, senza interessarmi troppo della logica di funzionamento, e mi sono fermato al ciclo:



for(int i=-1000;i<1000;i++)
{
temp2=equazione(i+1);
if((temp1<0 && temp2>0) || (temp1>0 && temp2<0))
{
ris[iter]=i;
iter++;
}
if(temp2==0)
{
cout<<"Una radice e' "<<i+1<<endl;
}
temp1=temp2;
}


ris un array composto da 3 elementi, l'indice iter cresce in modo indefinito...

P.S. Elimina inoltre il return nella funzione trova.

Bellerofonte90
11-01-2008, 17:53
quella un array dentro la funzione, se la chiami riso f lo stesso errore!!!! Non centra nulla il ris del main.

prova a cambiare il nome di ris dentro la funzione e vedrai che f lo stesso effetto

Bellerofonte90
11-01-2008, 18:03
se tu intendi che non c' un freno al puntatore iter, ti ricordo che l'array "radici" del main che passo alla funzione cambiandogli nome e chiamandola "riso" di 20 massimo cellette di memoria. siccome un'equazione con un'incognita che arrivi ad elevarsi fino alla ventesima non l'ho mai vista anche se possibile, poco probabile, quindi non c' rischio che il pc trovi pi di venti risultati...

pallinopinco
11-01-2008, 18:27
se tu intendi che non c' un freno al puntatore iter, ti ricordo che l'array "radici" del main che passo alla funzione cambiandogli nome e chiamandola "riso" di 20 massimo cellette di memoria. siccome un'equazione con un'incognita che arrivi ad elevarsi fino alla ventesima non l'ho mai vista anche se possibile, poco probabile, quindi non c' rischio che il pc trovi pi di venti risultati


C' poco da ricordare agli altri e molto da studiare... Cosa succede se cerchi di accedere al trentesimo elemento di un array di 20 items?

Prova ad aggiungere un cout << iter << endl; prima della riga ris[iter]=i; per vedere dopo quante iterazioni si verifica il buffer overflow.

Bellerofonte90
11-01-2008, 18:36
ragionando impossibile che vada fino a quel numero, c' qualche errore da qualche altra parte visto che un'equazione per esempio con un grado massimo alla 5a pu avere solo 5 soluzioni e visto che quella di prova alla 4a ne avr solo 4 e perch arriva fino a sforare i 20.... sar sicuramente l'if che vede le veriazioni di segno... grazie per tutto

come posso vedere se uno dei due temp cambia disegno in confronto all'altro?

pallinopinco
11-01-2008, 19:00
ragionando impossibile che vada fino a quel numero


Non ho tempo di analizzare il tuo codice, per posso dirti che il programma va in crash con iter = 44... Vedi un po' tu perch arriva a quel valore.



Decidi
2

0
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44

Bellerofonte90
11-01-2008, 19:10
perfavore, qualcuno mi faccia venire un'idea su come posso far capire al pc che una variabile in confronto all'altra ha cambiato segno ed passata per esempio, la variabile1 era positiva e la veriabile2 negativa allora il programma deve andare a salvare una certa cosa, sicuramente c' l'if, ma la condizione non riesco proprio a trovarla

ecco la funzione



void trova (long double radici[],int & iter)
{
iter=0;
long double temp1,temp2;

temp1=equazione(-1000);

for(int i=-1000;i<1000;i++)
{
temp2=equazione(i+1);
if((temp1<0 && temp2>0)||(temp1>0 && temp2<0))
{
radici[iter]=i;
iter++;
}
if(temp2==0)
{
cout<<"Una radice e' "<<i+1<<endl;
}
temp1=temp2;
}
}

pallinopinco
11-01-2008, 20:30
[QUOTE]
temp2=equazione(i+1);
[QUOTE]

Prima di pensare a come risolvere il problema dei cambiamenti di segni dovresti considerare che valuti la funzione solo per valori interi, i viene incrementato di 1 ad ogni iterazione, ma la soluzione potrebbe trovarsi tra 2 interi...

Bellerofonte90
11-01-2008, 20:57
quella solo una mezza abbozza, poi il do-while infinito del mani pensa ad affinare, ma st vedendo che c' qualche errore logico anche l... il vero algoritmo dicotonico quello nel main, il do-while infinito

Loading