Building a calculator in C#, stuck on doing the math stuff.

Started by
49 comments, last by eFoDay 11 years, 10 months ago

If your not acquainted with the idea of reading books on the subject of C# such as in this case. I recommend you start, it would give you exactly what you want if you can find the right book. Examples along with "problem sets" that you can solve to further your skills which is what it sounds like your looking for. Such as Head First C#, 2E: A Learner's Guide to Real-World Programming with Visual C# and .NET


Links that might help:
http://www.c-sharpco....com/Beginners/
http://www.homeandle...arp/csharp.html
http://www.fincher.o...es/csharp.shtml


but I have stated I have a million books on the subject..including the one you provided. I will go through the tutorials on the sites you provided. I know about csharpcorner but never really did the stuff on it.
Advertisement
hai just get the total thing as a string and and then trim the thing using the operators like (+,-,*,/) and store the variable proceeding it in a array and do your calculation
I made this just for u smile.png

[source lang="csharp"]using System;
using System.Collections.Generic;

namespace TestAppForGameDev
{
class Program
{
static List<Calculation> calculation = new List<Calculation>();
static void Main(string[] args)
{
Console.Write("Set a inital value to multiply/add/minus/divide from: ");
string inital_string = Console.ReadLine();
double initalvalue = double.Parse(inital_string);
string calculationappearance = inital_string;
Console.WriteLine("Add more values using /add, /minus, /divide or /multiply.");
Console.WriteLine("Use /calc to calculate the answer!");
while (true)
{
string input_string = Console.ReadLine();
string[] input_string_split = input_string.Split(' '); //separate the type of cmd to the specified cmd data, string[] is a array.
if (input_string_split[0] == "/add")
{
calculation.Add(new Calculation(double.Parse(input_string_split[1]), Calculation.Type.Add));
calculationappearance += " + " + input_string_split[1];
}
else if (input_string_split[0] == "/minus")
{
calculation.Add(new Calculation(double.Parse(input_string_split[1]), Calculation.Type.Minus));
calculationappearance += " - " + input_string_split[1];
}
else if (input_string_split[0] == "/divide")
{
calculation.Add(new Calculation(double.Parse(input_string_split[1]), Calculation.Type.Divide));
calculationappearance += " / " + input_string_split[1];
}
else if (input_string_split[0] == "/multiply")
{
calculation.Add(new Calculation(double.Parse(input_string_split[1]), Calculation.Type.Multiply));
calculationappearance += " * " + input_string_split[1];
}
else if (input_string_split[0] == "/calc" || input_string_split[0] == "/calculate")
{
Console.WriteLine("Calculating " + calculationappearance);
double result = initalvalue;
for (int i = 0; i < calculation.Count; i++)
{
switch (calculation.type)
{
case Calculation.Type.Add:
result += calculation.value;
break;
case Calculation.Type.Minus:
result -= calculation.value;
break;
case Calculation.Type.Multiply:
result *= calculation.value;
break;
case Calculation.Type.Divide:
result /= calculation.value;
break;
}
}
Console.WriteLine("Result: " + result.ToString());
Console.ReadLine(); //make sure user can see result
break; //get out of the while loop and close the program
}
}
}
}
class Calculation
{
public enum Type { Add, Minus, Divide, Multiply }
public double value;
public Type type;
public Calculation(double value, Type type)
{
this.value = value;
this.type = type;
}
}
}
[/source]
Mess around with it, change things around, look up what the List is that is in the source here on MSDN, look up enums too, there are code examples everywhere on there. I hope i helped...
I did a little searching around, and ended up finding exactly what I was looking for in terms of code to learn from.

[source lang="csharp"]using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Calculator
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

string sOperator = "";
string sFirstValue = "";

private void button0_Click(object sender, EventArgs e)
{
textBox1.Text += button0.Text;
}

private void button1_Click(object sender, EventArgs e)
{
textBox1.Text += button1.Text;
}

private void button2_Click(object sender, EventArgs e)
{
textBox1.Text += button2.Text;
}

private void button3_Click(object sender, EventArgs e)
{
textBox1.Text += button3.Text;
}

private void button4_Click(object sender, EventArgs e)
{
textBox1.Text += button4.Text;
}

private void button5_Click(object sender, EventArgs e)
{
textBox1.Text += button5.Text;
}

private void button6_Click(object sender, EventArgs e)
{
textBox1.Text += button6.Text;
}

private void button7_Click(object sender, EventArgs e)
{
textBox1.Text += button7.Text;
}

private void button8_Click(object sender, EventArgs e)
{
textBox1.Text += button8.Text;
}

private void button9_Click(object sender, EventArgs e)
{
textBox1.Text += button9.Text;
}

private void buttonAdd_Click(object sender, EventArgs e)
{
sFirstValue = textBox1.Text;

textBox1.Text = String.Empty;

sOperator = buttonAdd.Text;
}

private void buttonSubtract_Click(object sender, EventArgs e)
{
sFirstValue = textBox1.Text;

textBox1.Text = String.Empty;

sOperator = buttonSubtract.Text;
}

private void buttonMultiply_Click(object sender, EventArgs e)
{
sFirstValue = textBox1.Text;

textBox1.Text = String.Empty;

sOperator = buttonMultiply.Text;
}

private void buttonDivide_Click(object sender, EventArgs e)
{
sFirstValue = textBox1.Text;

textBox1.Text = String.Empty;

sOperator = buttonDivide.Text;
}

private void buttonEquals_Click(object sender, EventArgs e)
{
float result = 0;

switch (sOperator)
{
case "+":
result = float.Parse(sFirstValue) + float.Parse(textBox1.Text);
break;
case "-":
result = float.Parse(sFirstValue) - float.Parse(textBox1.Text);
break;
case "*":
result = float.Parse(sFirstValue) * float.Parse(textBox1.Text);
break;
case "/":
result = float.Parse(sFirstValue) / float.Parse(textBox1.Text);
break;
}
textBox1.Text = String.Empty;

textBox1.Text = Convert.ToString(result);
}

private void buttonClear_Click(object sender, EventArgs e)
{
textBox1.Text = String.Empty;
}
}
}
[/source]

Edit: I take it back, the code doesn't do what I'm looking for, I thought it did. It only does it after you hit =. Otherwise, you can only add two numbers.
Copying code out of google and books is not programming.

Copying code out of google and books is not programming.


I know this....

God forbid someone doesn't know how to do something and goes looking to get an idea.
Your confusing two distinct issues. There is the programs user interface, and its internal implementation. You are focussing on the user interface, and this is causing the internal implementation to become more complex.

You do not need to parse strings to do this. The strings could instead be inferred from some program state (in a more convenient format for computation).

Let us think about the operations you are exposing, while ignoring the interface. The user can use the 10 digits, and the 4 standard operators. Finally, there is a way to evaluate this. Let us design this system in English.

If we ignore operator precedence, we can model this simply as two lists - a list of numbers and a list of operators. There must always be at least as many numbers as operators, but there can be one more. We use a state machine to determine what should happen if the user presses a button.

If the user presses a digit:

  • If there as many operators as numbers, then append this digit to the numbers list.
  • If there are more numbers than operators, if the user presses a digit then multiple the last number by ten and add the digit.

You should eventually handle overflow, but this will suffice for the moment.

If the user presses an operator:

  • If there are less operators than numbers, then append the operator the user pressed.
  • If there as many operators as numbers then replace the last operator with the one the user wants.


If the user tries to evaluate:

  • If the lists are empty, then display an error (or do nothing).
  • If there are as many operators as numbers, then display an error (we need a final number to match the last operator).
  • If there are less operators than numbers, then iterate over both lists, using an accumulator set from the first number, and applying each operator to the accumulator and operator in turn.


Psuedo-code for this might look like;

enumeration Operator {
Plus, Minus, Multiply, Divide
}

type Calculator {

function digit(number x)

function operator(Operator operator)

function evaluate() -> number or Error
}


There is one missing piece - and that is allowing the U.I. to present the current state of the program. We can provide a function which will built a string representation of the expression string. You'll need to figure out how to translate this into a C# class. The key point is that the user interface is now decoupled from the internal representation.

You don't need to parse current string - the string is a textual representation of the program's state. By storing the program's state as a string, you are actually throwing away information that you knew as the string was being built.
Ok, after thinking over a little bit, I think I at least have the ball rolling. I managed to figure out a way to store the numbers without the math signs. I don't have any of the adding/subtracting/multiplying/dividing logic in yet. Still gotta figure that one out:

[source lang="csharp"]using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;

namespace Calculator
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}

List<string> numbers = new List<string>();
string currentString = "";
char[] mathSymbols = { '+', '-', '*', '/',' '};

private Boolean lastCharIsSymbol { get; set; }

bool add = false;
bool subtract = false;
bool multiply = false;
bool divide = false;

private void button0_Click(object sender, EventArgs e)
{
textBox1.Text += button0.Text;
lastCharIsSymbol = false;
}

private void button1_Click(object sender, EventArgs e)
{
textBox1.Text += button1.Text;
lastCharIsSymbol = false;
}

private void button2_Click(object sender, EventArgs e)
{
textBox1.Text += button2.Text;
lastCharIsSymbol = false;
}

private void button3_Click(object sender, EventArgs e)
{
textBox1.Text += button3.Text;
lastCharIsSymbol = false;
}

private void button4_Click(object sender, EventArgs e)
{
textBox1.Text += button4.Text;
lastCharIsSymbol = false;
}

private void button5_Click(object sender, EventArgs e)
{
textBox1.Text += button5.Text;
lastCharIsSymbol = false;
}

private void button6_Click(object sender, EventArgs e)
{
textBox1.Text += button6.Text;
lastCharIsSymbol = false;
}

private void button7_Click(object sender, EventArgs e)
{
textBox1.Text += button7.Text;
lastCharIsSymbol = false;
}

private void button8_Click(object sender, EventArgs e)
{
textBox1.Text += button8.Text;
lastCharIsSymbol = false;
}

private void button9_Click(object sender, EventArgs e)
{
textBox1.Text += button9.Text;
lastCharIsSymbol = false;
}

private void buttonAdd_Click(object sender, EventArgs e)
{
if (textBox1.Text == "" || lastCharIsSymbol)
return;
else
{
textBox1.Text += buttonAdd.Text;
currentString = textBox1.Text;
currentString.TrimEnd(mathSymbols);
numbers.Add(currentString);
lastCharIsSymbol = true;
add = true;
}
}

private void buttonSubtract_Click(object sender, EventArgs e)
{
if (textBox1.Text == "" || lastCharIsSymbol)
return;
else
{
textBox1.Text += buttonSubtract.Text;
currentString = textBox1.Text;
currentString.TrimEnd(mathSymbols);
numbers.Add(currentString);
lastCharIsSymbol = true;
subtract = true;
}
}

private void buttonMultiply_Click(object sender, EventArgs e)
{
if (textBox1.Text == "" || lastCharIsSymbol)
return;
else
{
textBox1.Text += buttonMultiply.Text;
currentString = textBox1.Text;
currentString.TrimEnd(mathSymbols);
numbers.Add(currentString);
lastCharIsSymbol = true;
multiply = true;
}
}

private void buttonDivide_Click(object sender, EventArgs e)
{
if (textBox1.Text == "" || lastCharIsSymbol)
return;
else
{
textBox1.Text += buttonDivide.Text;
currentString = textBox1.Text;
currentString.TrimEnd(mathSymbols);
numbers.Add(currentString);
lastCharIsSymbol = true;
divide = true;
}
}

private void buttonClear_Click(object sender, EventArgs e)
{
textBox1.Text = String.Empty;
}

private void buttonEquals_Click(object sender, EventArgs e)
{
if (add)
{

}

if (subtract)
{

}

if (multiply)
{

}

if (divide)
{

}
}
}
}[/source]

basically, I created a char array, involving the math symbols + whitespace; I trim that off the end, and then store that value into the List.

One thing occured to me just as I thought I got this. This isn't going to just keep adding on the numbers that were already in the textbox, to a new list slot will it?

For example, say you put 25 as the first number, that gets stored, then you hit + or w/e and put 86.

First list slot: 25
Second list slot: This won't be 2586 will it? Thats what concerns me.

EDIT: Close topic please, I can already see that this is going to be dead wrong. So I give up

First list slot: 25
Second list slot: This won't be 2586 will it? Thats what concerns me.


With the way you have it right now, it almost will, but it won't. Let's look at the code to see why. Here's a snippet from the code you just posted.

[source]

if (textBox1.Text == "" || lastCharIsSymbol)
return;
else
{
textBox1.Text += buttonMultiply.Text;
currentString = textBox1.Text;
currentString.TrimEnd(mathSymbols);
numbers.Add(currentString);
lastCharIsSymbol = true;
multiply = true;
}
[/source]

Firstly, String.TrimEnd() doesn't actually modify the string. It returns a copy of the string with whatever characters are in mathSymbols trimmed off. This is because in C#, strings are immutable. Practically speaking, this means that once a string object has a value, you CANNOT change it without creating a new string, so whenever you call a string method you want to take the return value of that method and use that instead of the original string object. Because of this, with the code you have now, you're actually adding the entire contents of the textbox, including the math symbols, to the number list! So let's change that TrimEnd() call to this:

[source]

currentString = textBox1.Text.TrimEnd(mathSymbols);
[/source]

Secondly, TrimEnd() will get you what you want, almost. You're correct in observing that with things the way it is right now, if you have "25 + 86", you'll get "2586," which is close but isn't quite what you want. This actually has a pretty easily solution - don't trim whitespace! Consider that because you've included ' 'in your list of "math symbols", all the spaces between the numbers will get trimmed. So let's stop doing that by changing our definition of mathSymbols to this:

[source]

char[] mathSymbols = { '+', '-', '*', '/'};
[/source]

In actual fact, this array better matches its name - it's a list of math symbols, not a list of math symbols and the space character.

Now when that code is run, currentString should contain "25 86". Now, I've already presented a string method in my last post here that can split up a string into an array of sub-strings...


EDIT: Close topic please, I can already see that this is going to be dead wrong. So I give up
[/quote]

You're doing decently so far. Who cares if it's dead wrong for now? That's how you learn - by making mistakes, learning why they're mistakes, and fixing them. Do you want to learn to program or not? If you can't handle being wrong once in a while, you must have trouble learning anything, never mind programming. I get that this is frustrating you, but if you want to accomplish anything you need to push past the frustration and keep trying.
I guess

This topic is closed to new replies.

Advertisement