Member Avatar for Erwin_Rosyid

I'm coding a calculator with display and controlls in separate forms. I've hit a block on several bugs but the most promenient one is:
- The calculator couldn't process more than ONE operator (2+2=OK but 2+2+2=4=NOT OK)
- sqrt function is quite broken

Sollution and related files (VC# 2010)

It's not an assignment so there isn't any time pressure for me, but can anyone help me with finished code or pseudocode that I could use?

Regards,
Erwin Rosyid

Okay, reading over your source code there are a few things I can point out to you that you might be interested in for shortening the amount of line's you'll have overall.

1) Since you're requiring access to Form1 in Form2 you can create a variable of Form1 in Form2 then request it in the constructor; this would help with assigning the whole Form2.Form1 thing. Also to get rid of the conditional where you're checking to see if Form2 has been disposed or not, it's not required. Instead move your declaration of Form2 into the area where you're calling Form2.

        // Inside Form2.cs
        private Form1 MainForm;

        public Form2(Form1 f1)
        {
            this.MainForm = f1;
            InitializeComponent();
        }

        // Form1.cs:
        public partial class Form1 : Form
        {
            /* Form2 frm2 = new Form2(); -- Remove this. */
            public Form1() {
                InitializeComponent();
            }

            public string getTextButton() {
                return callform2.Text;
            }

            private void callform2_Click(object sender, EventArgs e) {
                Form2 f2 = new Form2(this);
                f2.Show();
            }

That will ensure that Form2 is never disposed when called since you're only calling it from there. You can just declare, initialize, and use it from the method you're calling it in.

2) You can get rid of 'if', 'else if', 'else' on the 'opmode' variable and use switch structure. If you're unfamiliar with switch structure below is an example using your variable:

    switch (opmode) {
        case 0: doSomething(); break;
        case 1: doSomethingElse(); break;
        case 2: doSomethingDifferent(); break;
    }

3) When performing math of multiple operators you should perform the calculations as each parameter is passed; then just display the string of what's been done so far in a label or text box that's read only

    double Val1 = 0;
    double Val2 = 0;

    int NextOp = 0;
    int CurrentOp = 0;

    // For addition:
    private void AddButton_Click(object sender, EventArgs e) {
        switch (CurrentOp) {
            case 1: Val1 += Val2; break;
            case 2: Val1 -= Val2; break;
            case 3: Val1 *= Val2; break;
            case 4: Val1 /= Val2; break;
        }

        NextOp = 1;

        MainForm.DisplayLabel.Text += " + ";
        MainForm.CurrentValueLabel.Text = Val1.ToString();

        Val2 = 0;
    }

    // Storing the numbers to Value variables:
    private void ButtonZero_Click(object sender, EventArgs e) {
        Val2 = 0;
        MainForm.DisplayLabel.Text += "0";
        CurrentOp = NextOp;
    }

    // Pressing of equal button:
    private void EqualsButton_Click(object sender, EventArgs e) {
        switch (CurrentOp) {
            case 1: Val1 += Val2; break;
            case 2: Val1 -= Val2; break;
            case 3: Val1 *= Val2; break;
            case 4: Val1 /= Val2; break;
        }

        MainForm.CurrentValueLabel.Text = Val1.ToString();
        MainForm.DisplayLabel.Text = "";
    }

What I've supplied should give you a basic idea of how to build the calculator, as well as give you an idea on how to shorten up your source code a bit. I'll go through and write a basic 1 (op) 2 application for you and post the source within the hour so you can use it for reference, but what I've supplied should do the trick. :)

You're welcome,
Jamie

I did everything but fix the display string for you. The display string will keep adding the incorrect values, but the math stays correct. :)

Fix the display problem and you'll have a functioning calculator. :)

        private double Value1 = 0;
        private double Value2 = 0;

        private string Value2StringTemp = "";

        private int CurrentOp = 0;
        private int NextOp = 0;

        private void ButtonOne_Click(object sender, EventArgs e) {
            Value2StringTemp += "1";
            mathPerformed.Text += Value2StringTemp;
            Value2 = Convert.ToDouble(Value2StringTemp);

            CurrentOp = NextOp;
        }

        private void ButtonTwo_Click(object sender, EventArgs e) {
            Value2StringTemp += "2";
            mathPerformed.Text += Value2StringTemp;
            Value2 = Convert.ToDouble(Value2StringTemp);

            CurrentOp = NextOp;
        }

        private void ButtonPlus_Click(object sender, EventArgs e) {
            CurrentOp = CurrentOp == 0 ? 1 : CurrentOp;

            switch (CurrentOp) {
                case 1: Value1 += Value2; break;
                case 2: Value1 -= Value2; break;
                case 3: Value1 *= Value2; break;
                case 4: Value1 /= Value2; break;
            }

            NextOp = 1;

            Value2StringTemp = "";
            mathPerformed.Text += " + ";
            currentAnswer.Text = Value1.ToString();

            Value2 = 0;
        }

        private void ButtonMinus_Click(object sender, EventArgs e) {
            CurrentOp = CurrentOp == 0 ? 2 : CurrentOp;

            switch (CurrentOp) {
                case 1: Value1 += Value2; break;
                case 2: Value1 -= Value2; break;
                case 3: Value1 *= Value2; break;
                case 4: Value1 /= Value2; break;
            }

            NextOp = 2;

            Value2StringTemp = "";
            mathPerformed.Text += " - ";
            currentAnswer.Text = Value1.ToString();

            Value2 = 0;
        }

        private void ButtonDot_Click(object sender, EventArgs e) {
            Value2StringTemp += ".";
            mathPerformed.Text += Value2StringTemp;
            Value2 = Convert.ToDouble(Value2StringTemp);

            CurrentOp = NextOp;
        }

        private void ButtonEquals_Click(object sender, EventArgs e) {
            switch (CurrentOp) {
                case 1: Value1 += Value2; break;
                case 2: Value1 -= Value2; break;
                case 3: Value1 *= Value2; break;
                case 4: Value1 /= Value2; break;
            }

            currentAnswer.Text = Value1.ToString();
            mathPerformed.Text = "";
            Value2StringTemp = "";

            Value1 = 0;
            Value2 = 0;
            CurrentOp = 0;
            NextOp = 0;
        }

I did everything inside of Form1 because I didn't feel like making a second form for it. But it's not that hard to switch up. :)

Hope I helped,
Jamie

Also, for Square Root, Exponents, and so on, you'll have to perform the math in the same way I demonstrated; however there is one rule. You must perform the math on the number to be manipulated before performing the math on the manipulation. For example:

5 + 8 + SquareRoot(9). We know the answer to this is 16. Our computers know this as well, however they can't tell you the answer just by looking at SquareRoot(9). They need to be told how to calculate that. So for something involving manipulation of a number you would perform the math in steps. Shall I explain?

With my example 5 + 8 + SquareRoot(9) we would first solve 5 + 8, giving us 13. Then we would solve for the square root of 9; which brings out new expression to 13 + 3. Thus giving us the answer of 16. But say the user wants to make it 5 + 8 + SquareRoot(9) + 4, which is equal to 20. To do this, we would solve the Square Root of 9 before performing math on 13 + SquareRoot(9). Then we would perform the math. So using the same algorithms I provided earlier (switch logic) you would add in an extra button called SquareRoot (or whatever you want to call it) that would serve as a notice to perform Square Root math. Meaning you would add a new variable called (for example) SpecialMath as type boolean. Then if SpecialMath is a true value, see which type of math it is, then perform that math before continuing:

    bool SpeicalMath = false;
    int SpecialMathIndex = 0;

    private void SquareRootButton_Click(object sender, EventArgs e) {
        SpecialMath = true;

        DisplayLabel.Text += " sqrt";
        SpecialMathIndex = 1;
    }

    private void AddButton_Click(object sender, EventArgs e) {
        if (SpecialMath) {
            switch (SpecialMathIndex) {
                case 1: Value2 = Math.Sqrt(Value2); break;
            }

            SpecialMath = false;
        }

        switch (CurrentOp) {
            case 1: Value1 += Value2; break;
            case 2: Value1 -= Value2; break;
            case 3: Value1 *= Value2; break;
            case 4: Value1 /= Value2; break;
        }
    }

The above source code is just pseudocode so there is a chance that it's slightly inaccurate. However it should be pretty close if it's not spot on. The above should read the math in sections and perform any special math before performing real math. The steps for solving special math problems like this one are always the same.

5 + 8 + SquareRoot(9) + 4
13 + SquareRoot(9) + 4
13 + 3 + 4 : 16 + 4
20

Step 3 is 2 steps in one. Make sure you always break down the special math first, then perform regular math.

Hope it helps,
Jamie

Member Avatar for Erwin_Rosyid

Solved, thanks for the input - already developed another simpler code :D

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.