My advice: Do not write this code yourself. Having written code that does this, there are some things to be aware of:
Parsing mathematical expressions is not a trivial problem, if you're going to do it correctly and fully. You have to consider things like the associativity of each operator: what happens if you find more than one of the same operator in an expression? Which one do you evaluate first? How do you deal with operators whose precedence changes depending on their context? (for example, the negation operator) These are hard questions, and very few implementations get it right.
As was mentioned in a comment on the question, there are some things that can do this for you already:
NSPredicate
. Pros: built-in, reasonably fast, decent precision. Cons: the exponent is parsed with incorrect associativity, not extensible, does not support implicit multiplication (i.e., 2(x*x)
), does not parse the negation operator correctly.
GCMathParser
. Pros: very fast, decent precision. Cons: not extensible, does not support implicit multiplication, does not parse the negation operator correctly.
DDMathParser
. Pros: excellent precision, extensible, supports implicit multiplication. Cons: not quite as fast as the other two, due to the parsing engine and high precision math
Obviously, I recommend DDMathParser
(I wrote it). In your case, you'd want to do something like this:
NSError *error = nil;
NSString *math = [DDExpression expressionFromString:@"2($x * $x) + 2" error:&error];
for (int x = 0; x < 100; ++x) {
NSNumber *variable = [NSNumber numberWithInt:x];
NSDictionary *sub = [NSDictionary dictionaryWithObject:variable forKey:@"x"];
NSNumber *value = [math evaluateWithSubstitutions:sub evaluator:nil error:&error];
NSLog(@"value: %@", value);
}
DDMathParser
is available on GitHub: https://github.com/davedelong/DDMathParser . Please be mindful of its license (free for use with attribution).
However, if you're ok with sacrificing some precision (and a couple of cases of it being incorrect) in exchange for blazing fast speed, I'd recommend using GCMathParser
.
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…