Universal Calculator

Pages: 12
I made a universal calculator that does just about anything from basic math to trigonometry. Any suggestions or constructive criticism would be nice.

http://www.4shared.com/file/eN7FmATB/Complex_Calculator.html
Nice job, you should try making it in a GUI and you will get noticed (If you spread it around the internet that is.)
How can I learn C++ graphics and what library should I use?
Try the Win32 API, learn it here: http://www.winprog.org/tutorial/
I would suggest maybe trying to keep away from platform-specific APIs unless there's a need of some sort (example: a requirement for a function that either doesn't exist or isn't/can't be well-implemented using a cross-platform library). That's a personal opinion, though.

I'd suggest the Qt framework. It's a bit large, but it has almost everything you could possibly need for application development, it comes with some useful tools, and it's cross-platform. :)

http://qt.nokia.com/

-Albatross
Any ideas for a good way to learn qt?
Pick a project, then implement it. Buy a Qt book as a reference for when you need to figure out how to do something.
I'd love to see this calculator given a nice GUI; the GNOME project pretty much wrecked their (previously) awesome calculator and I haven't yet found one that mixed a good GUI and decent features.
If you want, programmatic, I can help you (via AIM, its a IM chat program) make this into a GUI application within a max time of ten hours all together ;) (that is with me teaching you all the code completely)

let me know if you are interested.
Last edited on
few notes:
* it is enough to know the sides of the triangle to calculate it's area. see http://en.wikipedia.org/wiki/Heron's_formula
* you don't need to ask for pyramid's or cone's slant. see http://en.wikipedia.org/wiki/Pythagorean_theorem
* system is evil. see http://www.cplusplus.com/forum/articles/11153/
* you might want to solve equations of higher degree. see http://en.wikipedia.org/wiki/Durand–Kerner_method

over all, it has useful things, but it isn't very comfortable. a gui would improve that, but the really awesome thing would be parsing equations.

I never thought of making a geometric calculator. seems challenging. I might make one. when I have some time..
If I were to make an attempt at parsing equations (which I have tried in previous versions of the calculator), would i have to read each character in a string and determine if it is a number, operator, decimal pt., etc. or is there a way to do this more efficiently. From my past experiences, it gets pretty complicated once you start reading numbers because if the next character is a number it changes the value of the final number and things get pretty tricky.
You could use enums in the menu selection (also changing the if-else to switch-case)
1
2
3
4
5
6
7
//quadratic.cpp
int* PrimeFactor(double d) {
  int factors[50];
//...
  return factors; //address of local variable returned
}
//factoring calculator.cpp (is this repeated?) has the same issue. 

In Quadratic::GetSquareRoot() you are reinventing the wheel in a real inefficient way. Why don't you use sqrt ?
A few things that are misleading:

1. Quadratic.cpp and Quadratic.h are files from a previous version of the calculator that I integrated into version 2 (I did a lot of consolidating). Sorry for including them. I guess I forgot to delete them.

2. The GetSquareRoot() function has a misleading name; its purpose is not to find the square root of something, but it is rather to find the number under the radical sign reduced to a non-perfect square.

Also, what do you mean by using enums in the menu selection?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
bool RegularCalculator() {
    enum operation{Add=1, Sub, Mult, Div, Exp, Sqrt, Back, Exit};
    int CaclFunction;
    //...
    cout << "(1)Addition\n(2)Subtraction\n(3)Multiplication\n(4)Division\n(5)Exponentiation\n(6)Square Root\n(7)Back\n(8)Exit" << endl;
    cin >> CalcFunction;
    
    switch(CalcFunction){
    case Add: case Sub: case Mult: case Div: case Exp:
        cout << "Enter the first number: ";
        cin >> Num1;
        cout << "Enter the second number: ";
        cin >> Num2;
        if (CalcFunction != Div and Num2 != 0)
            cout << "The answer is ";
    case Sqrt:
        cout << "Enter the number: ";
        cin >> dNum1;
        if (dNum1 >= 0)
            cout << "The answer is ";
    }
    
    switch(CalcFunction){
    case Add: cout << Calc.Addition() << "." << endl; break;
    case Sub: cout << Calc.Subtraction() << "." << endl; break;
    //...
    case Back: break;
    case Exit: ExitIndicator = true; break;
    default: cout << "Invalid choice. Try again." << endl;
    }
    
    if (CalcFunction != Back and CalcFunction != Exit)
        Delay();
    return ExitIndicator;
}
about parsing.
consider input "2+3*(4+5)"
then (ignoring things in parentheses) find the operator of lowest precedence ( + or - ) and split it at that place.
you get 2 and "3*(4+5)"
"3*(4+5)" becomes 3 and "(4+5)".
if there are no operators in the string, try removing the parentheses. you then have "4+5". repeat the operation and you'll get 4 and 5.
you should have a function float evaluate(const char* input); to do the job:
if input has operators, split it and return evaluate(first_half) + evaluate(second_half);
else if input has parentheses, return evaluate(input_without_parentheses);
if input is "number", return number;
I'll give it a shot.

In the meantime, is there any other functionality that should go into this? I'm trying to integrate as much as possible in this one project.
I have an issue with the parsing:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
for (unsigned int i = 0;i < sCalculation.length();++i) {
		if (IsOperator(sCalculation[i])) {
		
			cOperator = sCalculation[i];

			//Store left side number
			for (unsigned int j = i - 1;j >= 0;j--)
				if (IsNumber(sCalculation[j]))
					iLeftSide += GetNumber(sCalculation[j]) * static_cast<int>(pow(static_cast<double>(10), static_cast<int>(i - j - 1)));
			//Store right side number
			for (unsigned int j = i + 1;j < sCalculation.length();j++)
				if (IsNumber(sCalculation[j]))
					iRightSide = iRightSide * 10 + GetNumber(sCalculation[j]);
			
		} 
	}


This returns a runtime error. Anyone know why?
Last edited on
I fixed the error: in the first nested for the fact that j was unsigned caused some issues.

Here's my code for this so far:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
#include <iostream>
#include <string>
#include <cmath>
using namespace std;

bool IsNumber(char);
bool IsOperator(char);
int GetNumber(char);
int PerformCalculation(int,int,char);

int main() {

	string sCalculation;
	int iLeftSide = 0;
	int iRightSide = 0;
	char cOperator;
	cin >> sCalculation;

	for (unsigned int i = 0;i < sCalculation.length();++i) {
		if (IsOperator(sCalculation[i])) {
		
			cOperator = sCalculation[i];

			//Store left side number
			for (int j = i - 1;j >= 0;j--)
				if (IsNumber(sCalculation[j]))
					iLeftSide += GetNumber(sCalculation[j]) * static_cast<int>(pow(static_cast<double>(10), static_cast<int>(i - j - 1)));
			//Store right side number
			for (unsigned int j = i + 1;j < sCalculation.length();j++)
				if (IsNumber(sCalculation[j]))
					iRightSide = iRightSide * 10 + GetNumber(sCalculation[j]);
			
		} 
	}

	int answer = PerformCalculation(iLeftSide, iRightSide, cOperator);
	cout << answer << endl;

	system("pause");
	return 0;
}

bool IsNumber(char element) {
	if (element <= '9' && element >= '0')
		return true;
	else
		return false;
}

bool IsOperator(char element) {
	if (element == '+' || element == '-' || element == '*' || element == '/')
		return true;
	else
		return false;
}

int GetNumber(char element) {
	return element - 48;
}

int PerformCalculation(int num1, int num2, char operation) {
	if (operation == '+')
		return num1 + num2;
	else if (operation == '-')
		return num1 - num2;
	else if (operation == '*')
		return num1 * num2;
	else if (operation == '/')
		return num1 / num2;
	else
		return 0;
}
if you enter "2 + 2", cin >> will read "2" (it stops at gaps) use getline instead.
line 27 has way too much casting.
overall your number parsing is a bit complex and only works for ints. let someone else do the work for you, when you can: http://www.cplusplus.com/articles/numb_to_text/
don't use ints everywhere. or 1 / 2 will be 0.
do that recursive function for more complex inputs.
I finished a basic version of a parsing calculator. Here it is so far:

http://www.4shared.com/file/q5v85bUw/Main.html

It's really unorganized and messy so forgive me. If anybody has suggestions for how to separate the code into a non-linear form please tell me. Any suggestions are as always encouraged.
Pages: 12