Using this expression-calculator in your iPhone, you can do advanced arithmetic calculations in a single step. No need to do multiple steps or memorize the intermediate results, for calculating the result of a single arithmetic expression.
For example, in order to evaluate the result of (8+5)*(7+2) in a traditional calculator, you have to calculate the result of (8+5) and (7+2) separately and then multiply the result of these two sub-expressions (13 and 9 in this case). Also, you have to memorize these results (or use Memory option in calculator) in order to do the third calculation (13*9 in this case). Using this expression-calculator, you can find the result of (8+5)*(7+2) in a single step. You can enter the full-expression and find the evaluated result in a single step.
Data Structures
An expression is an array of tokens. The Token class given below, is used to hold a single token in the input expression.
//RawToken class
@interface RawToken : NSObject
{
TokenType Type;
NSString *LinearToken;
int Index;
}
@property (nonatomic) TokenType Type;
@property (nonatomic, retain) NSString *LinearToken;
@property (nonatomic) int Index;
@end
The input expression can contain numbers and operators only. That is, a token can be a number or operator. We have created the following two classes namely Constant and Operator in order to represent a token in the expression.
//Constant class
@interface Constant : NSObject
{
PrimitiveDataType DataType;
NSString *Value;
}
@property (nonatomic) PrimitiveDataType DataType;
@property (nonatomic, retain) NSString *Value;
@end
//Operator class
@interface Operator : NSObject
{
OperatorSymbol Symbol;
NSString *SymbolText;
int OperandCount;
int PrecedenceLevel;
OperatorAssociativity Associativity;
}
@property (nonatomic) OperatorSymbol Symbol;
@property (nonatomic, retain) NSString *SymbolText;
@property (nonatomic) int OperandCount;
@property (nonatomic) int PrecedenceLevel;
@property (nonatomic) OperatorAssociativity Associativity;
@end
The TokenType, PrimitiveDataType, OperatorSymbol and OperatorAssociativity are enumerations defined as follows.
//TokenType
typedef enum { OperatorToken, ConstantToken } TokenType;
//PrimitiveDataType
typedef enum { Number, Text } PrimitiveDataType;
//OperatorSymbol
typedef enum { Plus, Minus, Multiply, Divide, Modulus, Power, OpenParenthesis, CloseParenthesis } OperatorSymbol;
//OperatorAssociativity
typedef enum { LeftToRight, RightToLeft } OperatorAssociativity;
Evaluating the Expression
This program uses Shunting-yard Algorithm to convert the input expression from infix to postfix form before evaulating the result. This algorithm is explained here, in detail with a live usable demo.
After the input expression is converted from infix-form to postfix-form, the following code is used to evaluate the result of postfix-form of the expression.
+ (double)Evaluate:(NSMutableArray*)postfixTokens
{
NSMutableArray *stack = [[NSMutableArray alloc] init];
//start evaluation
for(int index = 0; index < [postfixTokens count]; index+=1)
{
RawToken *token = [postfixTokens objectAtIndex:index];
if(token.Type == ConstantToken) //if constant
{
[stack addObject:token];
}
else if(token.Type == OperatorToken) //if operator
{
RawToken *temp = [stack lastObject];
[stack removeLastObject];
RawToken *top = [stack lastObject];
[stack removeLastObject];
RawToken *resultToken = [ExpressionEvaluator EvaluateArithmetic:top with:temp op:token];
[stack addObject:resultToken];
}
}
//take last token in stack as result
//(there should be only one token left in the stack)
if([stack count] == 1)
{
RawToken *top = [stack lastObject];
double result = [top.LinearToken doubleValue];
return(result);
}
return(0.0);
}
The EvaluateArithmetic function in above code is used to find the result of arithmetic operation of a single operator. This function is given below:
+ (RawToken*)EvaluateArithmetic:(RawToken *)token1 with:(RawToken *)token2 op:(RawToken *)op
{
OperatorSymbol operatorSymbol = [Operator ParseOperatorSymbol:[op.LinearToken characterAtIndex:0]];
double number1 = [token1.LinearToken doubleValue];
double number2 = [token2.LinearToken doubleValue];
double result = 0.0;
switch (operatorSymbol)
{
case Plus:
result = number1 + number2;
break;
case Minus:
result = number1 - number2;
break;
case Multiply:
result = number1 * number2;
break;
case Divide:
result = number1 / number2;
break;
case Modulus:
result = (int)number1 % (int)number2;
break;
case Power:
result = pow(number1, number2);
break;
default:
result = 0.0;
}
RawToken *resultToken = [[RawToken alloc] init];
resultToken.Type = ConstantToken;
resultToken.LinearToken = [NSString stringWithFormat:@"%lf", result];
return(resultToken);
}
Screenshots
Click on the image to enlarge.
|
Sample Calculations |
|
Example of Syntax Error |
Downloads for this article
File |
Language |
Tools |
iPhone-Expression-Calculator-Source 829.74 kb (180 downloads) |
Objective C |
iOS SDK 4.3, Xcode 3.2 |