Expressionvalue

Hello, I have two problems, which I hope you can answer me. The first: I would like on swift 4, transform a string type "pow (2.0,2.0)" to perform through my program power of. I can transform some strings of type sqrt or basic formula via the expressionValue command. But the pow does not work. The second: I will always like to swift 4, calculate a set of points x from -1000 to +1000 for the expression "pow (x, 2.0)" but this one only works in positive. Could you help me ? Thanks in advance ! Maxime

Can you show your present code ?


First question


I understand that you have as input


let input : String = "pow (2.0,2.0)"


and you want to execute pow (2.0,2.0)


A simple way is to parse the string to extract pow and 2.0 and 2.0


I did the following quick and dirty and tested in playground:

let op = "pow (2.0, 3.0)"
let openBracketIndex = op.index(of: "(") ?? op.startIndex      // test for nil if "(" missing
let closeBracketIndex = op.index(of: ")") ?? op.startIndex     // test for nil if ")" missing
let operatorName = op.prefix(upTo: openBracketIndex).trimmingCharacters(in: CharacterSet.whitespacesAndNewlines)     // thazt should be "pow"

let operatorStartIndex = op.index(openBracketIndex, offsetBy : 1)
let operatorEndIndex = op.index(closeBracketIndex, offsetBy : -1)
let terms = op[operatorStartIndex...operatorEndIndex]     // That should be "2.0, 2.0", with some extra space

let factors = terms.split(separator: ",").map() { $0.trimmingCharacters(in: CharacterSet.whitespacesAndNewlines) }     // get rid of extras spaces
let firstFactor = Float(factors[0]) ?? 0.0
let secondFactor = Float(factors[1]) ?? 1.0

if operatorName == "pow" {          // Could adapt to other func
    let result = powf(firstFactor, secondFactor)
    print(result)
}


Second question


as 2.0 is square, negative will work

So just call x * x !

Otherwise, use absolute value


let xAbs = abs(x)
let x2 = pow(xAbs, 2.0)


In fact, it is even possible to compute directly the power of a negative number.

The trick is that -1 = exp(i π) // i * Pi


I note ** for power of


so -2.0 = exp(i π) * 2.0

so (-2.0) ** 3.5 = (exp(i π) ** 3.5) * (2.0 ** 3.5) = exp (3.5 i π) * pow(2.0, 3.5)

And then convert exp (3.5 i π) to cos (3.5 i π) + i sin (3.5 i π)


Here it is obviously :

(-2.0) ** 2.0 = (exp(i π) ** 2.0) * (2.0 ** 3.5) = exp (2.0 i π) * pow(2.0, 3.5)

As exp (2 i π) = 1

result is pow(2.0, 3.5) as anticipated.


The func to compute the powIm return a couple (imaginary number)


func powIm(x: Float, y: Float) -> (real: Float, im: Float) {
    if x >= 0 {
        return (powf(x, y), 0)
    }
    let val = powf(-x, y)
    let c = cos(.pi * y)
    let real = (abs(c) > 2e-07 ) ? cos(.pi * y) * val : 0     // avoid rounding artefact
    let s = sin(.pi * y)
    let im = (abs(s) > 2e-07 ) ? sin(.pi * y) * val : 0
   return (real, im)
}


called as

    let result = powIm(firstFactor, secondFactor)


for op = "pow (-2.0, 3.0)"

returns (real: -8.0, im: 0.0)


for op = "pow (-2.5, 3.2)"

returns (real: -15.1832914, im: -11.031291)

Hello,


Thank you for your code and your help !

My code was:

  1. let formule = pow(x,3.0)
  2. let x = -2.0 //example
  3. let expression = NSExpression(format: formule)
  4. let objet = ["x":x]
  5. let expression1 = NSExpression(format: formule)
  6. let ResultatFonction = expression1.expressionValue(with: objet, context: nil)as?Double


My wish is to automatically calculate the formula pow (x, y) for x between -100 and 100 and y between 1 and 10.

I agree for the absolute, but only if the power is an even number.

If you compute pow(x, y) with y integer, that works. Even if y is odd.


let x = pow(-2.0, 3.0) yields -8.0


So, if y is always integer, you can use directly pow()

But if y is not integer, it will not work, and the meaning of pow(x, y) in that case requires to use imaginary numbers.

So are questions 1 and 2 solved for you ?

Yes, Thank for your help !

Good luck. Maybe one day you will need these complex numbers.


And don't bforget to mark the thread as closed.

Expressionvalue
 
 
Q