New User?   Join Now     Login            Forgot Password?    
iPhone Expression Calculator  (17300 hits)
 Share this Article
 
Posted by Prabu Arumugam on Nov-25-2010
Languages: Objective-C

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

 Share this Article

 Comments on this Article
Comment by jituu on May-28-2016
not able to register
Comment by lazyguy2489 on Apr-01-2013
Thank. it's helpful.
Comment by patel on Jan-17-2012
very good
Comment by emma1980 on Oct-06-2011
Nice! It helped me so much to learn Objective-C. Can you please upload the part for Signal_Click? I am confused with writing its code. Many thanks!
 Post your comment here
Your Name
Your Email
Comment
Post Comment

About      Terms      Contact