Sir, i have a numerical method project. I want to be different, so i try to make a program that can read user input, ex : sin(x+3)^(x*3^x), and find the root of the equation. I already implemented Reverse Polish Notation, and also shunting-yard algorithm. But, i found out that all my friends focused on the design, not about the advanced code. So, i want to make my code better by giving a graphic represented the function. I have an idea, with drawing each node of each value of x, with minimal range of x compared to the size of screen. The problem is, i don't know how to draw in c++. I want to add some GUI, and I also don't know how to do it.
Here is my work to prove that i have try. Sorry for the comments, i wrote in bahasa Indonesia.

#include<iostream>
#include<math.h>
#include<string.h>
#include<iomanip>
using namespace std;

string post[100];  //menampung bentuk postfix dari fungsi yang diinput user
int ukuranPost=0;  //banyak sel post yang terisi

double shunting(double); //shunting-yard algorithm
void postfix(string);  //mengubah infix menjadi postfix
double convert(string);  //mengubah angka dalam string menjadi angka dalam double
double satuOperand(string,double);  //operasi aritmatik dengan 1 operand
double duaOperand(string,double,double);  //operasi aritmatik dengan 2 operand
void bisection(double); //metode bisection
void falsePosition(double);  //metode false position
void secant(double);  //secant methods

double convert(string inputnya)
{
    int start=inputnya.length();
    double total=0;
    for (int i=0;i<inputnya.length();i++)
    {
        if(inputnya[i]=='.')
            start=i;
    }
    if(start==inputnya.length()) //tidak ada koma
    {
        for(int i=0;i<start;i++)
        {
            total+=(int(inputnya[i])-48)*pow(10,start-i-1);
        }
    }
    else
    {
        for(int i=0;i<start;i++)
        {
            total+=(int(inputnya[i])-48)*pow(10,start-i-1);
        }
        for(int i=start+1;i<inputnya.length();i++)
        {
            total+=(int(inputnya[i])-48)*pow(10,start-i);
        }
    }
    return total;
}

double satuOperand(string operatorr,double operand)
{
    if (operatorr=="sin")
        return sin(operand);
    else if (operatorr=="cos")
        return cos(operand);
    else if (operatorr=="tan")
        return tan(operand);
    else if (operatorr=="log")
        return log10(operand);
    else if (operatorr=="ln")
        return log(operand);
}

double duaOperand(string operatorr, double operand1, double operand2)
{
    if (operatorr=="+")
        return (operand1+operand2);
    else if (operatorr=="-")
        return (operand1-operand2);
    else if (operatorr=="*")
        return (operand1*operand2);
    else if (operatorr=="/")
        return (operand1/operand2);
    else if (operatorr=="^")
        return (pow(operand1,operand2));
}

int prioritas(string operatorr)
{
    if (operatorr=="sin" || operatorr=="cos" || operatorr=="tan" || operatorr=="log" || operatorr=="ln")
        return 1;
    else if (operatorr=="^")
        return 2;
    else if (operatorr=="*" || operatorr=="/")
        return 3;
    else if (operatorr=="+" || operatorr=="-")
        return 4;
    else
    {
        //tidak mungkin terjadi, karena asumsi tidak ada error handling
    }
}


void postfix(string input)
{
     string stack[100];
     int flagPost=0;
     int flagStack=0;
     
     for (int i=0;i<input.length();i++)
     {
         int mark=i;
         if (isdigit(input[i]))
         {
             while(isdigit(input[i+1]) || input[i+1]=='.')
             {
                  i++;
             }
             post[flagPost]=input.substr(mark,i-mark+1);
             flagPost++;
         }
         else if(input[i]=='-' && i==0 || input[i]=='-' && !isdigit(input[i-1]) && input[i-1]!='x' && input[i-1]!=')')
         {
              input=input.substr(0,i)+"(0-1)*"+input.substr(i+1);
              i--;
         }
		 else if(input[i]=='x')
		 {
			 post[flagPost]="x";
			 flagPost++;
		 }
		 else if(input[i]=='(')
		 {
              stack[flagStack]="(";
              flagStack++;
         }
         else if(input[i]==')')
         {
              while (stack[flagStack-1]!="(")
              {
                    post[flagPost]=stack[flagStack-1];
                    flagPost++;
                    flagStack--;
              }
              if(flagStack>0)
                    flagStack--;
         }
         else
         {
             if (!isalpha(input[i]))
             {
                  //bengong
             }
             else
             {
                  while(!isdigit(input[i+1]) && input[i+1]!='x' && input[i+1]!='(')
                  {
                       i++;
                  }
             }
             string tmp = input.substr(mark,i-mark+1);
             
             //push ke stack operator
             if (flagStack==0 || stack[flagStack-1]=="(")  //stack kosong, langsung push
             {
                  stack[flagStack]=tmp;
                  flagStack++;  //flag top stack
             }
/*             else if(flagStack!=0 && stack[flagStack-1]=="(")  // langsung push kalo ketemu kurung buka
             {
                  stack[flagStack]=tmp;
                  flagStack++;
             }
*/
             else
             {   //prioritas diperhatikan
                 int stackOpTrakir = prioritas(stack[flagStack-1]); //priortitas top stack
                 while (prioritas(tmp)>=stackOpTrakir && stack[flagStack-1]!="(")
                 {
                      post[flagPost]=stack[flagStack-1];
                      flagPost++;
                      flagStack--;
                      if(flagStack==0)
                          break;
                      else
                          stackOpTrakir = prioritas(stack[flagStack-1]);
                 }
                 stack[flagStack]=input.substr(mark,i-mark+1);
                 flagStack++;
             }
         }
         //cout<<"iterasi "<<i<<endl;
         //cout<<"post  : ";
         //for (int b=0;b<flagPost;b++)
         //    cout<<post[b]<<" ";
         //cout<<endl;
         //cout<<"stack : ";
         //for (int b=0;b<flagStack;b++)
         //    cout<<stack[b]<<" ";
         //cout<<endl<<endl;
     }
     for (int i=flagStack-1;i>=0;i--)
     {
         post[flagPost]=stack[i];
         flagPost++;
     }
     cout<<endl;
     
     //block ini berguna untuk memeriksa hasil postfix
     //for (int a=0;a<flagPost;a++)
     //{
     //    cout<<post[a]<<endl;
     //}
     
     
     //menghitung berapa isi sel post yang terpakai
     //berguna pada fungsi int shunting di bawah
     while(post[ukuranPost]!="")
     {
         ukuranPost++;
     }

}

double shunting(double x)
{
    double tmp[100];
    int flagTmp=0;
    //flagTmp menunjuk ke sel yang akan diisi
    //flagStack dan flagPost menunjuk ke sel yang akan diisi
    
    for (int i=0;i<ukuranPost;i++)
    {
        if (isdigit(post[i][0]))
        {
            //ubah menjadi integer            //masukan ke stack tmp;
            tmp[flagTmp]=convert(post[i]);
            flagTmp++;
        }
        else if(post[i]=="x")
        {
             //post int x ke stack tmp;
             tmp[flagTmp]=x;
             flagTmp++;
        }
        else
        {
            //bagian2 operator
            if(post[i]=="sin" || post[i]=="cos" || post[i]=="tan" || post[i]=="log" || post[i]=="ln")
            {    //1 operand
                tmp[flagTmp-1]=satuOperand(post[i],tmp[flagTmp-1]);
            }
            else
            {
                tmp[flagTmp-2]=duaOperand(post[i],tmp[flagTmp-2],tmp[flagTmp-1]);
                flagTmp--;
            } 
        }
    }
    return tmp[0];
}

void bisection(double es)
{
    double ea=100; //approximation error
    int iterasi=0; //menghitung berapa iterasi yang diperlukan
    
    //Bagian ini adalah bisection
    cout<<"\n\nMetode pertama : Bisection\n";
    double xl,xr,xm; //xl adalah x left, xr adalah x right, dan xm adalah x mid
    cout<<"Masukkan nilai x kiri : ";
    cin>>xl;
    cout<<"Masukkan nilai x kanan : ";
    cin>>xr;
    
    double fxl,fxr,fxm; //f(xl),f(xr),f(xm)
    fxl=shunting(xl);
    fxr=shunting(xr);
    cout<<fxl<<" "<<fxr<<endl;
    while(fxl*fxr>=0)
    {
        if(fxl==0)
        {
            cout<<"Akarnya adalah "<<xl<<endl;
            cout<<"Jadi, kita tidak perlu menghitung lagi."<<endl;
            goto bisectionoff;
        }
        else if (fxr==0)
        {
            cout<<"Akarnya adalah "<<xr<<endl;
            cout<<"Jadi, kita tidak perlu menghitung lagi."<<endl;
            goto bisectionoff;
        }
        else if (xl==xr)
        {
            cout<<"Input xl dan xr dengan angka yang berbeda, harap diulangi.\n";
            cout<<"Masukkan nilai x kiri : ";
            cin>>xl;
            cout<<"Masukkan nilai x kanan : ";
            cin>>xr;
            fxl=shunting(xl);
            fxr=shunting(xr);
        }
        else
        {
            cout<<"Tidak ada akar di antara "<<xl<<" dan "<<xr<<endl;
            cout<<"Coba ulangi dengan kombinasi xl dan xr yang berbeda.\n";
            cout<<"Masukkan nilai x kiri : ";
            cin>>xl;
            cout<<"Masukkan nilai x kanan : ";
            cin>>xr;
            fxl=shunting(xl);
            fxr=shunting(xr);
        }
    }
    //sampai sini input f(xl)*f(xr) sudah lebih kecil dari nol. Inisialisasi selesai.
    double tampung; //menampung xm pada iterasi sebelumnya.
    printf("%-11s %-11s %-11s %-11s %-11s %-11s %-11s\n","xl","xm","xr","f(xl)","f(xm)","f(xr)","ea");
    while(ea>es)
    {
        iterasi++;
        xm=(xl+xr)/2;
        if(iterasi>1)
        {
            ea=fabs((xm-tampung)/xm)*100;
        }
        fxm=shunting(xm);
        printf("%-11f %-11f %-11f %-11f %-11f %-11f %-11f\n",xl,xm,xr,fxl,fxm,fxr,ea);
        if(fxl*fxm<0)
        {
            xr=xm;
            fxr=shunting(xr);
        }
        else
        {
            xl=xm;
            fxl=shunting(xl);
        }
        tampung=xm;
    }
    cout<<"Akarnya adalah : "<<xm<<" dan ditemukan pada iterasi ke-"<<iterasi<<endl;
bisectionoff:
             ;
}

void falsePosition(double es)
{
    double ea=100; //approximation error
    int iterasi=0; //menghitung berapa iterasi yang diperlukan
    
    //Bagian ini adalah bisection
    cout<<"\n\nMetode kedua : False Position\n";
    double xl,xr,xm; //xl adalah x left, xr adalah x right, dan xm adalah x mid
ulangfalse: ;
    ea=100;
    iterasi=0;    
    cout<<"Masukkan nilai x kiri : ";
    cin>>xl;
    cout<<"Masukkan nilai x kanan : ";
    cin>>xr;
    
    double fxl,fxr,fxm; //f(xl),f(xr),f(xm)
    fxl=shunting(xl);
    fxr=shunting(xr);
    while(fxl*fxr>=0)
    {
        if(fxl==0)
        {
            cout<<"Akarnya adalah "<<xl<<endl;
            cout<<"Jadi, kita tidak perlu menghitung lagi."<<endl;
            goto falseoff;
        }
        else if (fxr==0)
        {
            cout<<"Akarnya adalah "<<xr<<endl;
            cout<<"Jadi, kita tidak perlu menghitung lagi."<<endl;
            goto falseoff;
        }
        else if (xl==xr)
        {
            cout<<"Input xl dan xr dengan angka yang berbeda, harap diulangi.\n";
            cout<<"Masukkan nilai x kiri : ";
            cin>>xl;
            cout<<"Masukkan nilai x kanan : ";
            cin>>xr;
            fxl=shunting(xl);
            fxr=shunting(xr);
        }
        else
        {
            cout<<"Tidak ada akar di antara "<<xl<<" dan "<<xr<<endl;
            cout<<"Coba ulangi dengan kombinasi xl dan xr yang berbeda.\n";
            cout<<"Masukkan nilai x kiri : ";
            cin>>xl;
            cout<<"Masukkan nilai x kanan : ";
            cin>>xr;
            fxl=shunting(xl);
            fxr=shunting(xr);
        }
    }
    //sampai sini input f(xl)*f(xr) sudah lebih kecil dari nol. Inisialisasi selesai.
    double tampung; //menampung xm pada iterasi sebelumnya.
    printf("%-11s %-11s %-11s %-11s %-11s %-11s %-11s\n","xl","xm","xr","f(xl)","f(xm)","f(xr)","ea");
    while(ea>es)
    {
        iterasi++;
        xm=xr-fxr*(xl-xr)/(fxl-fxr);
        if(iterasi>1)
        {
            ea=fabs((xm-tampung)/xm)*100;
        }
        fxm=shunting(xm);
        printf("%-11f %-11f %-11f %-11f %-11f %-11f %-11f\n",xl,xm,xr,fxl,fxm,fxr,ea);
        if(fxl*fxm<0)
        {
            xr=xm;
            fxr=shunting(xr);
        }
        else
        {
            xl=xm;
            fxl=shunting(xl);
        }
        tampung=xm;
        if(iterasi==5000)
        {
            cout<<"Kombinasi xl dan xr ini tidak memungkinkan kita memperoleh akarnya.\n";
            cout<<"Coba ulangi dengan kombinasi xl dan xr yang berbeda.\n";
            goto ulangfalse;
        }
    }
    cout<<"Akarnya adalah : "<<xm<<" dan ditemukan pada iterasi ke-"<<iterasi<<endl;
falseoff:
             ;
}

void secant(double es)
{
    double ea=100; //approximation error
    int iterasi=0; //menghitung berapa iterasi yang diperlukan
    
    //Bagian ini adalah secant methods
    cout<<"\n\nMetode ketiga : Secant Methods\n";
    double x1,x2,x3; //xl adalah x left, xr adalah x right, dan xm adalah x mid
    cout<<"Masukkan dua buah nilai x untuk inisialisasi.\n";
ulangsecant:
            ;
    ea=100;
    iterasi=0; 
    cout<<"x1 = "; cin>>x1;
    cout<<"x2 = "; cin>>x2;
    
    double fx1,fx2,fx3; //f(xl),f(xr),f(xm)
    fx1=shunting(x1);
    fx2=shunting(x2);
    while(fx1==0 ||fx2==0 || x1==x2)
    {
        if(fx1==0)
        {
            cout<<"Akarnya adalah "<<x1<<endl;
            cout<<"Jadi, kita tidak perlu menghitung lagi."<<endl;
            goto secantoff;
        }
        else if (fx2==0)
        {
            cout<<"Akarnya adalah "<<x2<<endl;
            cout<<"Jadi, kita tidak perlu menghitung lagi."<<endl;
            goto secantoff;
        }
        else if (x1==x2)
        {
            cout<<"Input x1 dan x2 dengan angka yang berbeda, harap diulangi.\n";
            cout<<"Masukkan nilai x1 : ";
            cin>>x1;
            cout<<"Masukkan nilai x2 : ";
            cin>>x2;
            fx1=shunting(x1);
            fx2=shunting(x2);
        }
    }
    //sampai sini input f(xl)*f(xr) sudah lebih kecil dari nol. Inisialisasi selesai.
    printf("%-11s %-11s %-11s %-11s %-11s %-11s %-11s\n","x1","x2","x3","f(x1)","f(x2)","f(x3)","ea");
    while(ea>es)
    {
        iterasi++;
        x3=x2-fx2*(x1-x2)/(fx1-fx2);
        if(iterasi>1)
        {
            ea=fabs((x3-x2)/x3)*100;
        }
        fx3=shunting(x3);
        printf("%-11f %-11f %-11f %-11f %-11f %-11f %-11f\n",x1,x2,x3,fx1,fx2,fx3,ea);
        x1=x2;
        x2=x3;
        fx1=shunting(x1);
        fx2=shunting(x2);
        if(iterasi==5000)
        {
            cout<<"Tidak ada akar yang bisa ditemukan dengan kombinasi x1 dan x2 ini.\n";
            cout<<"Coba masukkan kombinasi yang lain.\n";
            goto ulangsecant;
        }
    }
    cout<<"Akarnya adalah : "<<x3<<" dan ditemukan pada iterasi ke-"<<iterasi<<endl;
secantoff:
          ;
}

int main()
{
    string input;
    
    cout<<"\t\tSelamat Datang di Program Penarikan Akar Secara Numerik\n\n";
    cout<<"Masukkan fungsi dalam x yang hendak dicari akarnya.\nJangan lupa membaca petunjuk pada laporan."<<endl;
    cout<<"Fungsi : ";
    cin>>input; //infix
    postfix(input); //mengubah input menjadi postfix
    
    double s; //s adalah jumlah bilangan signifikan yang diinginkan
    double es; //prespecified error
    
    cout<<"Masukkan jumlah bilangan signifikan yang diinginkan : ";
    cin>>s;
    es=0.5*pow(10,2-s);
    
    //mengerjakan bagian bisection
    bisection(es);
    
    //mengerjakan bagian false position
    falsePosition(es);
    
    //mengerjakan bagian secant
    secant(es);
        
    cin>>input;
    return 0;
}

thanks sir for your help.

Recommended Answers

All 3 Replies

Thanks sir, i will try.. :D

sir, is that for borland cpp?

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.