Blogger Widgets

Search This Blog

Saturday, 11 August 2012

Reverse Polish Calculator in C

                
                   Recently while done the exercises from KNR, I got an interesting excersise for calculator,..It is Reverse polish calculator. The major advantage of this is that this method saves our time, becouse here we can write a mathematical expression without using parentheses and brackets.
                 Here you never have to account for the parentheses while doing calculations. The process is similar to the way you learned math on paper. You can see the intermediary results as you perform your computations rather than just the answer at the end. This is an extremely helpful byproduct. Math teachers are using this feature to improve student understanding of mathematics. An intermediate result allows the user to check the results and correct errors more easily. It's easier to follow the stream of calculation. The user defines the priority of operators. RPN is logical because the user first gives the number and then tells what to do with it.

                     for eg : 
                       The reverse polish notation of (1 - 2) * (4 + 5) this
                        is entered as ----         1 2 - 4 5 + *


                     The implementation is simple. Each operand is pushed onto a stack; when an operator arrives,the proper number of operands (two for binary operators) is popped, the operator is applied to them, and the result is pushed back onto the stack. In the example above, for instance, 1 and 2 are pushed, then replaced by their difference, -1. Next, 4 and 5 are pushed and then replaced
by their sum, 9. The product of -1 and 9, which is -9, replaces them on the stack. The value on the top of the stack is popped and printed when the end of the input line is encountered.
                     For this I write a simple code
Code


#include<stdio.h>
#include<math.h>    //for including fmod and sin exp pow
#include<stdlib.h>    //including atof



#define MAXOP 100 // max size of operator or operant
#define NUMBER '0'        //identifieng nos
#define NAME 'n'        //indentifing math functions

int getop(char []);
void push(double);
double pop(void);
void clear(void);
void mathfunction(char s[]);


/*******************************************************
********Reverse Polish Calculator***********************
********************************************************
Eg : for (1-2)*(4+5) we give data like this
        1 2 - 4 5 + *
o/p        Result : 9
********************************************************/

main()
{
    int type;
    double op2,temp;
    char s[MAXOP];

    while ((type = getop(s)) != EOF){
        switch (type){
        case NUMBER:
            push(atof (s));
            break;
        case NAME:
            mathfunction(s);
            break;
        case 't':
            op2 = pop();
            printf("The top element = %.8g",op2);
            push(op2);
            break;
        case 's':
            op2 = pop();
            temp = pop();
            push(op2);
            push(temp);
            break;
        case 'c':            //clear
            clear();
            break;
        case 'd':        //dublicating
            op2 = pop();
            push(op2);
            push(op2);
            break;   
        case '+':
            push(pop() + pop());
            break;
        case '*':
            push(pop() * pop());
            break;
        case '-':
            op2 = pop();
            push(pop() - op2);
            break;
        case '/':
            op2 = pop();
            if(op2 != 0.0)
                push(pop() / op2);
            else
                printf("error: zero divisor\n");
            break;
        case '%':
            op2 = pop();
            if(op2 != 0.0)
                push(fmod(pop(), op2));
            else
                printf("error: zero divisor\n");
            break;       
        case '\n':
            printf("\tResult\t=\t%.8g\n", pop());
            break;
        default:
            printf("error: unknwn command %s\n", s);
            break;
        }
    }


    return 0;
}


/********************************************************************
**************** math fuctions calculation***************************
*********************************************************************/

#include<string.h>

void mathfunction(char s[])
{
    int op2;

    if(strcmp(s,"sin") == 0)
        push(sin(pop()));
    else if(strcmp(s,"cos") == 0)
        push(cos(pop()));
    else if(strcmp(s,"exp") == 0)
        push(exp(pop()));
    else if(strcmp(s,"pow") == 0){
        op2 = pop();       
        push(pow(pop(),op2));
    }
    else
        printf("Error..%s.Not a math function\n",s);
}
           

#define MAXVAL 100        //maximum depth of val stack

int sp = 0;
double val[MAXVAL];    //value stack

/*********************************************************
*********push: push f onto value stack********************
*********************************************************/
void push(double f)
{
    if (sp < MAXVAL)
        val[sp++] = f;
    else
        printf("error: stack full,can't push %g\n", f);
}

/*********************************************************
********pop: pop and return top value from stack**********
*********************************************************/
double pop(void)
{
    if (sp > 0)
        return val[--sp];
    else{
        printf("error: stack empty\n");
        return 0.0;
    }
}

/****************** for clearing stack*******************/
void clear(void)
{
    sp = 0;
}


#include<stdio.h>
#include<string.h>
#include<ctype.h>


int getch(void);
void ungetch(int c);

/********************************************************
******getop: get next character or numeric operand********
********************************************************/
int getop(char s[])
{
    int i = 0, c, next;

  
       while((s[0] = c = getch()) == ' ' || c == '\t')        //skip white space
              ;
       s[1] = '\0';
  
       if(isalpha(c)){
              i = 0;
              while(isalpha(s[i++] = c ))
                 c = getch();    
              s[i-1] = '\0';
              if(c != EOF)
                ungetch(c);
              return NAME;
       }   
  
       if(!isdigit(c) && c != '.')
             return c;                
  
          c = getch();

       while(isdigit(s[++i] = c))
              c = getch();
       
       if(c == '.')                 /* Collect fraction part. */
              while(isdigit(s[++i] = c = getch()))
                 ;
          s[i] = '\0';
          if(c != EOF)
             ungetch(c);
          return NUMBER;
}





#define BUFSIZE 100

char buf[BUFSIZE];          //buffer for ungetch
int bufp = 0;            //next free position in buf

int getch(void)    //get a possibly pushed-back character
{
    return (bufp > 0) ? buf[--bufp] : getchar();
}

void ungetch(int c)
{
    if (bufp >= BUFSIZE)
        printf("ungetch: too many characters\n");
    else
        buf[bufp++] = c;
}

No comments:

Post a Comment

Blogger Widgets