I'm registering a summation function that is sum(expression,initial,final)
. The expression
contains the independent variable x
and the initial
and final
are integers. For example, sum(2x,2,4)
should return 2*2+3*2+4*2=18
. However, I have trouble substituting x
in the expression
for every value between initial
and final
. Here are my code and it doesn't work. Can anyone tell me how to fix it?
//sum(expr (dependent on x),initial,final)
[evaluator registerFunction:^DDExpression *(NSArray *args, NSDictionary *vars, DDMathEvaluator *eval, NSError *__autoreleasing *error) {
DDExpression *final = nil;
if([args count] == 3){
DDExpression *expr = [args objectAtIndex:0];
DDExpression *start = [args objectAtIndex:1];
DDExpression *end = [args objectAtIndex:2];
//test whether start and end are integers
double startDouble = [[start evaluateWithSubstitutions:nil evaluator:evaluator error:nil] doubleValue];
double endDouble = [[end evaluateWithSubstitutions:nil evaluator:evaluator error:nil] doubleValue];
int startInt = (int)startDouble;
int endInt = (int)endDouble;
if (((startDouble-startInt)>0.9999 || (startDouble-startInt)<0.0001) && ((endDouble-endInt)>0.9999 || (endDouble-endInt)<0.0001)) {
//start and end are integers
double resultSum = 0;
for (int i=startInt; i<=endInt; i++) {
NSNumber *xValue = [NSNumber numberWithInt:i];
NSDictionary *substitution = [NSDictionary dictionaryWithObjectsAndKeys:xValue,@"x", nil];
NSNumber *valueOfExpr = [expr evaluateWithSubstitutions:substitution evaluator:evaluator error:nil];
resultSum = resultSum + [valueOfExpr doubleValue];
}
final = [DDExpression numberExpressionWithNumber:[NSNumber numberWithDouble:resultSum]];
}
}
return final;
}forName:@"sum"];
DDMathParser author here.
There are two things wrong, and one thing suboptimal.
"2x"
. That's fine, except thatx
is being interpreted as a function, but inside your for loop you're treatingx
as if it were a variable. You either need to fundamentally alter how your function works, or use the form2 * $x
(or just2$x
) as the first parameter to your function.doubleValue
off the evaluated arguments, just get theintegerValue
instead and avoid the whole double-to-int conversion.Here's how I'd clean up your function (although you should probably do a bit more in the way of filling in the
error
out parameter):With this, you can do
sum2(2*$x, 2, 4)
and it will evaluate to 18.