Click here to Skip to main content
15,881,281 members
Articles / Programming Languages / C++
Article

Simple extensible RPN based calculator class

Rate me:
Please Sign up or sign in to vote.
3.64/5 (8 votes)
19 Oct 20033 min read 50.1K   1.5K   20   5
This article is about a simple yet easily extensible class that allows to perform arithmetic calculations.

Sample Image - calctest.jpg

Introduction

This article describes a simple yet extensible C++ class for performing arithmetic calculations. You can use it when you need to calculate an expression that isn't known at the compile time. Its primary use is, I guess, for calculator programs, and then - what ever you'd think its useful for.

The calculations are based on Reverse Polish Notation technique invented almost a hundred years ago - it was easiest to implement. You can find out more about RPN at http://www.calculator.org/rpn.html

How to use it

To use the class you just need to include an "calctypes.h" in your project and to create an object of this class where you'd like it to be. The demo Project is written with WTL 7.0 and the source code depends on WTL's CString (located in "atlmisc.h") which is a serious flaw, generally speaking. You can look if it could be easily replaced with a MFC CString, or maybe just a char*.

Then when you need to calculate something you just call the Calculate(LPSTR, LPSTR) function with the expression as a first parameter and a variable list as a second. It will return the calculated value.

expression should contain only numbers, operators and variables (which I believe is everything other then the previous two). Numbers consist of '0' thru '9' and a '.', operator labels are configured in "calctypes.h". You should try it yourself, I always used names like "x" and "y" for vars. An example "Sin(x+y-Pow(2 +Cos(x-y),x*y))". Note that I treat a parenthesis as an operator.

variablelist is a semicolon separated list of equalities like this "x=12;y=31;z=2.3323" and there shouldn't be a trailing semicolon.

How to extend it

There is only a simple limited number of operators defined in "calctypes.cpp" and you will probably want to add something to your taste. All my effort while writing this class was to make it easy to implement new operators. You can create operators like "Indicator" or "Magnitude" or "Gradient" and others with this class. With a slight modification of the class you can even implement a different sets of operators which could be used when calculating an expression. The limit is that all operators should have no more then 3 arguments. If anyone knows an advanced technique that could be used to implement and "n" argument operators in my class, please let me know.

Now straight to the point. The code that calculates the expressions does not depend on defined operators in any way. You should do the following to add a new arithmetic operator to the calculator class:

Steps:

  1. Define a function that takes 3 pointers to doubles and returns a double.

    It should conform to the following typedef :

    typedef double (*TThreeArgFnPtr) (double * in_pdArg1,
        double* in_pdArg2 = NULL,double* in_pdArg3 = NULL);

    You should place it in a "calctypes.cpp" file and it should look like that:

    double Addition(double * in_pdArg1,double* in_pdArg2 = NULL,
        double* in_pdDummy = NULL) 
    {
        return *in_pdArg1 + *in_pdArg2;
    }
  2. Then create a global object of structure SOperator for your newly added operator.

    The structure's constructor takes 4 arguments - the first is the operators label, a string that will identify an operator in the expression, the second is its priority, the third is a number of operators arguments, and the last is a function that should be used for calculations (you just added it).

    You should end up with something like this:

    SOperator AdditionOperator(_T("+"),1,2,Addition);

    Once you made it you need to place a pointer to newly declared operator in the array of operators, which is

    SOperator* g_aUsualOperators[g_constNumberOfOperators] = ...

    The last thing to do is to modify the g_constNumberOfOperators variable declared in "calctypes.h"

You're done. I told you it'll be easy :) Use it freely, and don't hesitate to send feedback. Even critics. :)

TODO

There're however some real bad things about it:

  1. The code IS BUGGY. Sorry no time to polish it.
  2. Operators cant take more then 3 arguments. Anyone?
  3. Operator sets aren't implemented.
  4. Dependence on CString.
  5. Whachya say?? :)

License

This article has no explicit license attached to it but may contain usage terms in the article text or the download files themselves. If in doubt please contact the author via the discussion board below.

A list of licenses authors might use can be found here


Written By
Web Developer Sperasoft. Inc.
Russian Federation Russian Federation
I Graduated from Saint-Petersbufg State University in 2003.

Comments and Discussions

 
GeneralA Very Useful Class Pin
Karen030221-Dec-03 12:09
Karen030221-Dec-03 12:09 
GeneralA near instant (but constructive!) criticism Pin
Iain Clarke, Warrior Programmer20-Oct-03 3:25
Iain Clarke, Warrior Programmer20-Oct-03 3:25 
GeneralRe: A near instant (but constructive!) criticism Pin
Ilushka20-Oct-03 4:37
Ilushka20-Oct-03 4:37 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.