I have a string with multiple digits and operators
@\"5+4-9/10\".
How to get the result from it?
I want to use it within the calculator
Note that : You have to pass at least one float value.
I know that this is not the Best way , But Something like this can work for you.
NSString *formula = @"5+4-9/10";
NSString *str = [formula lastPathComponent];
formula = [formula stringByReplacingOccurrencesOfString:str withString:[NSString stringWithFormat:@"%@.0",str]];
NSString *strCal=[NSString stringWithString:formula];
NSExpression *exp=[NSExpression expressionWithFormat:strCal];
float result=[[exp expressionValueWithObject:nil context:nil] floatValue];
NSLog(@"result:%f",result);
You can use GCMathParser or DDMathParser.
Don't know if this is the most efficient method or not but Wrote to help you anyway...!!!
What about this -
NSString *formula = @"1+5*6";
NSExpression *exp = [NSExpression expressionWithFormat:formula];
NSNumber *resultForCustomFormula = [exp expressionValueWithObject:nil context:nil];
NSLog(@"%f", [resultForCustomFormula floatValue]);
EDIT :
Now I thought about your requirement and made a method using NSScanner You will not believe I didn't use NSScanner before Mr. Borrrden suggested me to use it and I found it awesome. See below method -
-(NSMutableString *)formatString:(NSString *)formula
{
// Let's check if there any wrong (.) value exm: 1/.2 or .7+3
// 1/0.2 and 0.7+3 are okay but above are incorrect so first fix them
NSString *str = formula;
NSInteger c = 0;
for(int i=0; i<[str length]; i++)
{
if([[NSString stringWithFormat:@"%c",[str characterAtIndex:i]] isEqualToString:@"+"] ||
[[NSString stringWithFormat:@"%c",[str characterAtIndex:i]] isEqualToString:@"-"] ||
[[NSString stringWithFormat:@"%c",[str characterAtIndex:i]] isEqualToString:@"/"] ||
[[NSString stringWithFormat:@"%c",[str characterAtIndex:i]] isEqualToString:@"*"])
{
if([str length] > i+1)
{
if([[NSString stringWithFormat:@"%c",[str characterAtIndex:i+1]] isEqualToString:@"."])
{
formula = [formula stringByReplacingCharactersInRange:NSMakeRange(i+1+c, 1) withString:@"0."];
c++;
}
}
}
}
// Now we will convert all numbers in float
NSString *aString;
float aFloat;
NSMutableString *formattedString = [[NSMutableString alloc]init];
NSScanner *theScanner = [NSScanner scannerWithString:formula];
while ([theScanner isAtEnd] == NO)
{
if([theScanner scanFloat:&aFloat])
{
[formattedString appendString:[NSString stringWithFormat:@"%f",aFloat]];
}
if([theScanner scanUpToCharactersFromSet:[NSCharacterSet decimalDigitCharacterSet] intoString:&aString])
{
[formattedString appendString:aString];
}
}
return formattedString;
}
This will convert (2.222/.4)+9999-7+0.7*.13 in to (2.222000/0.400000)+9999.000000-7.000000+0.700000*0.130000.
Just call this method before using NSExpression.
NSString *formula = @"(2.222/.4)+9999-7+0.7*.13";
NSString *formattedString = [self formatString:formula];
NSExpression *exp = [NSExpression expressionWithFormat:formattedString];
NSNumber *resultForCustomFormula = [exp expressionValueWithObject:nil context:nil];
NSLog(@"Result = %f", [resultForCustomFormula floatValue]);
//OutPut: Result = 9997.646484
Note: I'm not saying that it will work in all formula strings. May be it will not work in some case. But it will work in general equations.
You could parse "all" numbers to float:
NSMutableString *numericExpression = [NSMutableString stringWithString:@"4+3/2-7/4"];
NSMutableString *nExp=[NSMutableString stringWithString:@""];
BOOL innum=false;
BOOL dotfound=false;
for (NSInteger charIdx=0; charIdx<numericExpression.length; charIdx++){
NSString *substr=[NSString stringWithFormat:@"%C",[numericExpression characterAtIndex:charIdx]];
if (isdigit([numericExpression characterAtIndex:charIdx])) {
// in number
innum=true;
}else if ([substr isEqualToString:@"."]){
// dot found ...
innum=true;
dotfound=true;
}else{
// not in number
if (innum && dotfound) {
NSLog(@"all good (*).*");
}else if(innum && !dotfound){
NSLog(@"adding .0");
[nExp appendString:@".0"];
}
innum=false;
dotfound=false;
}
[nExp appendString:substr];
NSLog(@"%@",nExp);
}
NSExpression *expression = [NSExpression expressionWithFormat:nExp];
NSNumber *result = [expression expressionValueWithObject:nil context:nil];
NSLog(@"calc %@ = %@",nExp,result);