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
Expressionvalue
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:
- let formule = pow(x,3.0)
- let x = -2.0 //example
- let expression = NSExpression(format: formule)
- let objet = ["x":x]
- let expression1 = NSExpression(format: formule)
- 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.