Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to add a √ (nthroot) operator? #36

Open
horaceho opened this issue Jan 31, 2013 · 7 comments
Open

How to add a √ (nthroot) operator? #36

horaceho opened this issue Jan 31, 2013 · 7 comments

Comments

@horaceho
Copy link

What's the proper way to add the √ (nthroot) operator? such that:

3√8

will work as:

nthroot(8,3)

Is there an existing operator which I can use as a reference implementation?

@davedelong
Copy link
Owner

This is slightly complicated. The way things are right now, when the parser encounters a binary operator, it takes the left expression as the first argument and the right expression as the second argument. Thus, 3√8 would become nthroot(3, 8). I suppose I could put in a flag on the operator definition to flip the arguments around...

I'll think about this. I agree it's a good suggestion, but it'll require some work to do.

@davedelong
Copy link
Owner

The other thing to consider is that √64 is usually interpreted to mean "the square root of 64". So would 3√64 be "the cube root of 64" or "3 times the square root of 64"? I'm inclined to think it'd be the latter.

@horaceho
Copy link
Author

horaceho commented Feb 4, 2013

"3 times the square root of 64" is a result of Implicit Multiplication. Is possible to let binary operator to have higher precedence over implicit multiplication? And only works a unary operator when its left expression is not a number [while (6÷2)√8 is hopefully still nthroot(8,(6÷2))].

@KamranKhan-DL
Copy link

This is for Sqrt - Nthroot can be added in similar way

Step 1

In file _DDOperatorInfo.m under function

  • (NSArray *)_buildOperators { add following code

.....................
API Code
.....................
precedence++;
[operators addObject:[self infoForOperatorFunction:DDOperatorPower token:@"**" arity:DDOperatorArityBinary precedence:precedence associativity:DDOperatorAssociativityRight]];

Add Code Here -->

precedence++;
//sqrt
[operators addObject:[self infoForOperatorFunction:DDOperatorSqrt token:@"√" arity:DDOperatorArityUnary precedence:precedence associativity:DDOperatorAssociativityRight]];

Step 2

  • Now go to DDParserTypes.h and add following line of code

extern NSString *const DDOperatorSqrt;

  • Then in DDParserTypes.m add following code

NSString *const DDOperatorSqrt = @"Sqrt";

Step 3 (Finally)

Add the following code to your project (preferably in viewDidLoad method of your first view controller) before using the √ operator

DDMathFunction sqrtFunction = ^ DDExpression* (NSArray _args, NSDictionary *variables, DDMathEvaluator *evaluator, NSError *_error)
{
if ([args count] != 1) //Check for argument count
{
//fill in *error and return nil
*error = [NSError errorWithDomain:@"Arguments not equal to 1" code:10123 userInfo:nil];

        NSLog(@"%@", args);

        return nil;
    }

    NSNumber * n = [[args objectAtIndex:0] evaluateWithSubstitutions:variables evaluator:evaluator error:error];

    RETURN_IF_NIL(n);

    NSNumber *result = [NSNumber numberWithDouble:sqrt([n doubleValue])];

    return [DDExpression numberExpressionWithNumber:result];
};

[[DDMathEvaluator sharedMathEvaluator] registerFunction:sqrtFunction forName:@"Sqrt"];

@KamranKhan-DL
Copy link

For NthRoot

Step 1

In file _DDOperatorInfo.m under function

precedence++;

[operators addObject:[self infoForOperatorFunction:DDOperatorPower token:@"**" arity:DDOperatorArityBinary precedence:precedence associativity:DDOperatorAssociativityRight]];

precedence++;

//xsqrty
[operators addObject:[self infoForOperatorFunction:DDOperatorXSQY token:@"√" arity:DDOperatorArityBinary precedence:precedence associativity:DDOperatorAssociativityLeft]];

Step 2 (Follow like the above)

Step 3

DDMathFunction function = ^ DDExpression* (NSArray _args, NSDictionary *variables, DDMathEvaluator *evaluator, NSError *_error)
{
if ([args count] != 2)
{
//fill in *error and return nil
*error = [NSError errorWithDomain:@"Arguments not equal to 2" code:10122 userInfo:nil];

        NSLog(@"%@", args);

        return nil;
    }

    NSNumber * firstValue = [[args objectAtIndex:0] evaluateWithSubstitutions:variables evaluator:evaluator error:error];

    RETURN_IF_NIL(firstValue);

    NSNumber * secondValue = [[args objectAtIndex:1] evaluateWithSubstitutions:variables evaluator:evaluator error:error];

    RETURN_IF_NIL(secondValue);

    NSString *evalStr = [NSString stringWithFormat:@"nthroot(%@, %@)", secondValue, firstValue];

    NSNumber *result = [[DDMathEvaluator sharedMathEvaluator] evaluateString:evalStr withSubstitutions:nil];

    return [DDExpression numberExpressionWithNumber:result];
};
[[DDMathEvaluator sharedMathEvaluator] registerFunction:function forName:@"XSQY"];

@davedelong
Copy link
Owner

I just added API to define your own operators, so for now (at least) it's possible to add this yourself (check out the Wiki for details). I'm looking at what it would take to build this in, so I will leave this issue open.

@j259liu
Copy link

j259liu commented Sep 6, 2015

for square root, I just simple replace √( with sqrt( and it is a walk around to the problem...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

4 participants