Visualizzazione dei risultati da 1 a 10 su 10
  1. #1

    [C++] Programma risolvi equazioni

    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
    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.
    ALLA GUERRA!!!

  2. #2
    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:

    codice:
    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.
    "Se riesci a passare un pomeriggio assolutamente inutile in modo assolutamente inutile, hai imparato a vivere."

  3. #3
    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
    ALLA GUERRA!!!

  4. #4
    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...
    ALLA GUERRA!!!

  5. #5
    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.
    "Se riesci a passare un pomeriggio assolutamente inutile in modo assolutamente inutile, hai imparato a vivere."

  6. #6
    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?
    ALLA GUERRA!!!

  7. #7
    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
    "Se riesci a passare un pomeriggio assolutamente inutile in modo assolutamente inutile, hai imparato a vivere."

  8. #8
    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

    codice:
    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;
    	}
    }
    ALLA GUERRA!!!

  9. #9
    [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...
    "Se riesci a passare un pomeriggio assolutamente inutile in modo assolutamente inutile, hai imparato a vivere."

  10. #10
    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
    ALLA GUERRA!!!

Permessi di invio

  • Non puoi inserire discussioni
  • Non puoi inserire repliche
  • Non puoi inserire allegati
  • Non puoi modificare i tuoi messaggi
  •  
Powered by vBulletin® Version 4.2.1
Copyright © 2025 vBulletin Solutions, Inc. All rights reserved.