Page 1 of 1

a simple calculator needed

Posted: Mon Nov 14, 2011 9:46 am
by maximand
Hi,

Has anyone seen the code simple calculator?
I need to convert the simplest expression to a number.
For example 3+4+5,5 should be converted to 12,5
It's for personal financial app
http://sourceforge.net/projects/moneymanagerex/

Thanks

Re: a simple calculator needed

Posted: Mon Nov 14, 2011 12:11 pm
by doublemax
It may be a little overkill for your purpose, but i use muParser:
http://muparser.sourceforge.net/

Re: a simple calculator needed

Posted: Mon Nov 14, 2011 3:44 pm
by Auria
or bison, or antlr. Or just a parser you would write yourself. It really depends on how complete you want it, i.e. do you want * and / to be prioritary over + and -, do you want the ability to enter parentheses, etc.

Re: a simple calculator needed

Posted: Mon Nov 14, 2011 4:49 pm
by maximand
Auria wrote: Or just a parser you would write yourself.
Yes, I'll prefer parser if it created myself, but I am beginner in c++. I prefer transform available code to my needed. Can't write code from scratch.
It seems that there are no so simple calculators and I will write my.
Without parentheses, it's simple.

Re: a simple calculator needed

Posted: Sun Jan 13, 2013 1:44 pm
by maximand
I've created it by myself.
It support only main operations like + - / * and ()

Code: Select all

bool mmCalculator(wxString sInput, wxString& sOutput)
{
    //TODO: Fix Non standart number format
    sInput.Replace(wxT(")("), wxT(")*("));
    bool bResult = true;
    int a = sInput.Replace(wxT("("), wxT("("));
    int b = sInput.Replace(wxT(")"), wxT(")"));
    if (a != b) return false;
    if (a > 0)
    {
        for (size_t i = 0; i < sInput.Len(); i++)
        {
            if (sInput[i] == '(') a += i;
            if (sInput[i] == ')') b += i;
            if (sInput[i] == '(' && i > 0) bResult = bResult && (wxString(wxT("(+-*/")).Contains(sInput[i-1]));
            if (sInput[i] == ')' && i < sInput.Len()-1) bResult = bResult && (wxString(wxT(")+-*/")).Contains(sInput[i+1]));
        }
        if (a >= b || !bResult) return false;
    }

    wxString sTemp = sInput.Trim().Prepend(wxT("(")).Append(wxT(")"));
    wxString midBrackets, sToCalc;
    double dAmount = 0;

    while (sTemp.Contains(wxT("(")) && bResult)
    {
        dAmount = 0;
        size_t leftPos = sTemp.Find('(', true);
        size_t rightPos = sTemp.find(wxT(")"), leftPos);
        midBrackets = sTemp.SubString(leftPos, rightPos);
        midBrackets.Replace(wxT("(-"), wxT("(N"));
        sToCalc = midBrackets.SubString(1, midBrackets.Len()-2);
        if (sToCalc.IsEmpty()) bResult = false;
        double dTempAmount;
        sToCalc.Replace(wxT("*-"), wxT("M"));
        sToCalc.Replace(wxT("/-"), wxT("D"));
        sToCalc.Replace(wxT("+-"), wxT("-"));
        sToCalc.Replace(wxT("-+"), wxT("-"));
        sToCalc.Replace(wxT("+"), wxT("|"));
        sToCalc.Replace(wxT("-"), wxT("|-"));
        midBrackets.Replace(wxT("(N"), wxT("(-"));

        wxStringTokenizer token(sToCalc, wxT("|"));

        while (token.HasMoreTokens() && bResult)
        {
            double dSubtotal = 1;
            wxString sToken = token.GetNextToken();
            sToken.Replace(wxT("M"), wxT("|M"));
            sToken.Replace(wxT("D"), wxT("|D"));
            sToken.Replace(wxT("*"), wxT("|*"));
            sToken.Replace(wxT("/"), wxT("|/"));
            sToken.Replace(wxT("N"), wxT("-"));
            sToken.Prepend(wxT("*"));

            wxStringTokenizer token2(sToken, wxT("|"));
            while (token2.HasMoreTokens() && bResult)
            {
                wxString sElement = token2.GetNextToken();
                wxString sSign = sElement.Mid(0,1);
                sElement.Remove(0,1);
                if (sElement.ToDouble(&dTempAmount))
                {
                    if (sSign == wxT("*")) dSubtotal = dSubtotal*dTempAmount;
                    else if (sSign == wxT("M")) dSubtotal = -dSubtotal*dTempAmount;
                    else if (sSign == wxT("/") && dTempAmount != 0) dSubtotal = dSubtotal/dTempAmount;
                    else if (sSign == wxT("D") && dTempAmount != 0) dSubtotal = -dSubtotal/dTempAmount;
                    else bResult = false;
                }
                else
                    bResult = false;
            }
            dAmount += dSubtotal;
        }
        sTemp.Replace(midBrackets, wxString()<<dAmount);
    }
    if (sTemp.Contains(wxT("("))||sTemp.Contains(wxT(")"))) bResult = false;

    //if (bResult) mmex::formatDoubleToCurrencyEdit(dAmount, sOutput);
    if (bResult)  sOutput = wxString()<<dAmount;

    return bResult;
}

Re: a simple calculator needed

Posted: Fri Oct 11, 2013 10:01 am
by maximand
This code seems is popular.

It should be validator used for wxTextCtrl

https://sourceforge.net/p/moneymanagere ... lidators.h

Code: Select all

 textAmount_ = new mmTextCtrl( this, ID_DIALOG_TRANS_TEXTAMOUNT, "",
wxDefaultPosition, wxSize(110, -1),
wxALIGN_RIGHT|wxTE_PROCESS_ENTER, mmCalcValidator()); 
I became to understand classes and will redesign this code.

Re: a simple calculator needed

Posted: Sat Oct 12, 2013 9:15 am
by maximand
it has been updated

how to use

Code: Select all

#include "mmCalculator.h"
....
    textAmount_ = new wxTextCtrl( this, wxID_ANY, "",
        wxDefaultPosition, wxSize(110, -1),
        wxALIGN_RIGHT|wxTE_PROCESS_ENTER, mmCalcValidator());
....

    mmCalculator calc;
    if (calc.is_ok(textAmount_->GetValue()))
            textAmount_->SetValue(calc.get_result());

Re: a simple calculator needed

Posted: Fri Jan 04, 2019 11:56 am
by TobiasA
Is it allowed to include your code into own code? If yes, under which license?

Re: a simple calculator needed

Posted: Sun Feb 24, 2019 10:13 am
by maximand
You can use it as you wish.