Thomas Kilian Thomas Kilian - 1 month ago 14
Swift Question

Using overridden math function

Trying to compile this code

pow(10,2)
struct Test {
var i:Int
func pow(_ p:Int) -> Int { return pow(i,p) }
}
var s = Test(i:10)
s.pow(2)


gives me a compiler error. Obviously the standard math.h function
pow
was blinded out by Swift's scoping rules. This rather smells like a compiler error since the math.h version of
pow
has a different signature. Is there any way to invoke it, though?

Answer

There are two problems: The first is how pow(i,p) is resolved. As described in Swift 3.0: compiler error when calling global func min<T>(T,T) in Array or Dictionary extension, this can be solved by prepending the module name to the function call.

The second problem is that there is no pow function taking two integer arguments. There is

public func powf(_: Float, _: Float) -> Float
public func pow(_: Double, _: Double) -> Double

in the standard math library, and

public func pow(_ x: Decimal, _ y: Int) -> Decimal

in the Foundation library. So you have to choose which one to use, for example:

struct Test {
    var i:Int
    func pow(_ p:Int) -> Int {
        return lrint(Darwin.pow(Double(i),Double(p)))
    }
}

which converts the arguments to Double and rounds the result back to Int.

Alternatively, use iterated multiplication:

struct Test {
    var i: Int
    func pow(_ p:Int) -> Int {
        return (0..<p).reduce(1) { $0.0 * i }
    }
}

I observed at http://codereview.stackexchange.com/a/142850/35991 that this is faster for small exponents. Your mileage may vary.