2013-03-30 2 views
1

Я регистрирую функцию суммирования, которая равна sum(expression,initial,final). expression содержит независимую переменную x, а initial и final являются целыми числами. Например, sum(2x,2,4) должен возвращать 2 * 2 + 3 * 2 + 4 * 2 = 18. Однако у меня есть проблема с заменой x на expression для каждого значения между initial и final. Вот мой код, и он не работает. Может ли кто-нибудь сказать мне, как это исправить?Может ли кто-нибудь помочь исправить эту новую функцию DDMathParser?

//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"]; 
+0

Почему бы не обратиться непосредственно к Дейву ДеЛонгу? :) –

ответ

2

DDMathParser автор здесь.

Есть две вещи неправильно, и одна вещь неоптимальная.

  1. Неверно - вы не можете назвать эту функцию «суммой». "sum" is a built-in function, и built-in functions cannot be overridden.
  2. Неверно - первый параметр вашей функции: "2x". Это нормально, за исключением того, что x интерпретируется как функция , но внутри цикла for вы обрабатываете x, как если бы это была переменная. Вам либо необходимо принципиально изменить, как работает ваша функция, либо использовать форму 2 * $x (или просто 2$x) в качестве первого параметра вашей функции.
  3. Субоптимальный - вместо получения оцененных аргументов просто получите вместо этого integerValue и избегайте целого преобразования double-to-int.

Вот как я бы очистить вашу функцию (хотя вы, вероятно, следует сделать немного больше в способе заполнения параметра error выход):

[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]; 
     //get the start and end values 
     NSInteger startValue = [[eval evaluateExpression:start withSubstitutions:vars error:error] integerValue]; 
     NSInteger endValue = [[eval evaluateExpression:end withSubstitutions:vars error:error] integerValue]; 

     double sum = 0; 
     for (NSInteger i = startValue; i <= endValue; i++) { 
      NSDictionary *substitution = @{@"x": @(i)}; 
      NSNumber *value = [eval evaluateExpression:expr withSubstitutions:substitution error:error]; 
      sum += [value doubleValue]; 
     } 
     final = [DDExpression numberExpressionWithNumber:@(sum)]; 
    } 
    return final; 
} forName:@"sum2"]; 

С этим, вы можете сделать sum2(2*$x, 2, 4) и он будет оцениваться до 18.

+0

спасибо. У меня есть вопрос: когда я регистрировал функции раньше (и они хорошо работали), я написал «NSInteger startValue = [[оценщик оценивать выражение: start withSubstitutions: vars error: error] integerValue];' вместо 'NSInteger startValue = [[eval оценивать выражение : start withSubstitutions: vars error: error] integerValue]; '. Разница в том, что я отправляю сообщение 'оценщику' вместо' eval'. Можете ли вы сказать мне, в чем разница, и почему все в порядке? Кстати, перед регистрацией я объявил 'DDMathEvaluator * оценщик = [DDMathEvaluator sharedMathEvaluator]'. – zyl1024

+0

@ zyl1024 вам следует предпочесть, чтобы экземпляр «DDMathEvaluator» прошел в блок над тем, который вы захватили из-за пределов блока. –

Смежные вопросы