How to get the Power of some Integer in Swift language?

136,204

Solution 1

If you like, you could declare an infix operator to do it.

// Put this at file level anywhere in your project
infix operator ^^ { associativity left precedence 160 }
func ^^ (radix: Int, power: Int) -> Int {
    return Int(pow(Double(radix), Double(power)))
}

// ...
// Then you can do this...
let i = 2 ^^ 3
// ... or
println("2³ = \(2 ^^ 3)") // Prints 2³ = 8

I used two carets so you can still use the XOR operator.

Update for Swift 3

In Swift 3 the "magic number" precedence is replaced by precedencegroups:

precedencegroup PowerPrecedence { higherThan: MultiplicationPrecedence }
infix operator ^^ : PowerPrecedence
func ^^ (radix: Int, power: Int) -> Int {
    return Int(pow(Double(radix), Double(power)))
}

// ...
// Then you can do this...
let i2 = 2 ^^ 3
// ... or
print("2³ = \(2 ^^ 3)") // Prints 2³ = 8

Solution 2

Other than that your variable declarations have syntax errors, this works exactly how you expected it to. All you have to do is cast a and b to Double and pass the values to pow. Then, if you're working with 2 Ints and you want an Int back on the other side of the operation, just cast back to Int.

import Darwin 

let a: Int = 3
let b: Int = 3

let x: Int = Int(pow(Double(a),Double(b)))

Solution 3

Sometimes, casting an Int to a Double is not a viable solution. At some magnitudes there is a loss of precision in this conversion. For example, the following code does not return what you might intuitively expect.

Double(Int.max - 1) < Double(Int.max) // false!

If you need precision at high magnitudes and don't need to worry about negative exponents — which can't be generally solved with integers anyway — then this implementation of the tail-recursive exponentiation-by-squaring algorithm is your best bet. According to this SO answer, this is "the standard method for doing modular exponentiation for huge numbers in asymmetric cryptography."

// using Swift 5.0
func pow<T: BinaryInteger>(_ base: T, _ power: T) -> T {
    func expBySq(_ y: T, _ x: T, _ n: T) -> T {
        precondition(n >= 0)
        if n == 0 {
            return y
        } else if n == 1 {
            return y * x
        } else if n.isMultiple(of: 2) {
            return expBySq(y, x * x, n / 2)
        } else { // n is odd
            return expBySq(y * x, x * x, (n - 1) / 2)
        }
    }

    return expBySq(1, base, power) 
}

Note: in this example I've used a generic T: BinaryInteger. This is so you can use Int or UInt or any other integer-like type.

Solution 4

If you really want an 'Int only' implementation and don't want to coerce to/from Double, you'll need to implement it. Here is a trivial implementation; there are faster algorithms but this will work:

func pow (_ base:Int, _ power:UInt) -> Int {
  var answer : Int = 1
  for _ in 0..<power { answer *= base }
  return answer
}

> pow (2, 4)
$R3: Int = 16
> pow (2, 8)
$R4: Int = 256
> pow (3,3)
$R5: Int = 27

In a real implementation you'd probably want some error checking.

Solution 5

The other answers are great but if preferred, you can also do it with an Int extension so long as the exponent is positive.

extension Int {   
    func pow(toPower: Int) -> Int {
        guard toPower > 0 else { return 0 }
        return Array(repeating: self, count: toPower).reduce(1, *)
    }
}

2.pow(toPower: 8) // returns 256
Share:
136,204
林鼎棋
Author by

林鼎棋

Updated on July 09, 2020

Comments

  • 林鼎棋
    林鼎棋 almost 4 years

    I'm learning swift recently, but I have a basic problem that can't find an answer

    I want to get something like

    var a:Int = 3
    var b:Int = 3 
    println( pow(a,b) ) // 27
    

    but the pow function can work with double number only, it doesn't work with integer, and I can't even cast the int to double by something like Double(a) or a.double()...

    Why it doesn't supply the power of integer? it will definitely return an integer without ambiguity ! and Why I can't cast a integer to a double? it just change 3 to 3.0 (or 3.00000... whatever)

    if I got two integer and I want to do the power operation, how can I do it smoothly?

    Thanks!

  • Rudi Kershaw
    Rudi Kershaw almost 10 years
    It's good practice to explain why your code offers a solution, rather than just dumping code into an answer.
  • CLRBTH
    CLRBTH over 9 years
    And it's far from a correct power function. What about 0 as an exponent or any negative value.
  • wjl
    wjl about 9 years
    That replaces the standard xor operator. Using this will make your code behave in a very unexpected way to anyone who doesn't know you're overriding the single karat.
  • padapa
    padapa about 9 years
    So if you wanted to do this for Floats, would you do this: infix operator ^^ { } func ^^ (radix: Float, power: Float) -> Float { return Float(pow(Double(radix), Double(power))) }
  • padapa
    padapa about 9 years
    func ^^ (radix: Double, power: Double) -> Double { return Double(pow(Double(radix), Double(power))) }
  • Tim Arnold
    Tim Arnold about 9 years
    I found this didn't quite behave as I expected because the precedence was off. For an exponentiative operator, set precedence to 160 (see developer.apple.com/library/ios/documentation/Swift/Conceptu‌​al/… and developer.apple.com/library/ios/documentation/Swift/Conceptu‌​al/…) like so: infix operator ^^ { precedence 160 } func ^^... and so on
  • mklbtz
    mklbtz almost 8 years
    This is a completely valid answer. There are some instances where converting Ints to Doubles loses precision, and so that is not a viable solution for Int pow. Just try running Double(Int.max - 1) < Double(Int.max) in a Swift 3 REPL and you may be surprised.
  • mklbtz
    mklbtz almost 8 years
    To shorten it up, you could implement this with a reduce call. return (2...power).reduce(base) { result, _ in result * base }
  • Vanya
    Vanya over 7 years
    I really like this solution, but with Swift 3 it does not work. Any idea how to make it work?
  • Cody
    Cody over 7 years
    Any idea for how to use this (pow) for Boolean values? Double(Bool) throws an error and I can't seem to find anything about how to typecast a Boolean variable as a Double.
  • Grimxn
    Grimxn over 7 years
    Why would you want power for booleans? What do you mean by true x true or square root of false?
  • Cody
    Cody over 7 years
    In previous versions of swift I was using the Boolean value as a 0 or 1 input for the power function with -1 as the base to get 1 or -1 as an answer, which is a trick used a lot in infinite series in calculus. My background is more of mathematics than programming so I don't know if there is a better trick for mapping [1,0] to [-1,1]? It's about nine of the twenty six remaining errors my app has since updating to swift 3.
  • Grimxn
    Grimxn over 7 years
    func p(_ b: Bool) -> Double { return b?-1:1 } ?
  • Cody
    Cody over 7 years
    Thanks! I just needed a space before the question mark, saves me a lot of extra if statements I started using to fix the problem last night!
  • Adam Kaplan
    Adam Kaplan over 7 years
    A code quality note: I do not recommend actually defining this as ^^ because it’s very difficult to visually spot ^ vs ^^ in code reviews, and the two operators both accept and return Int, but give extremely different results. You’d just be begging for a nasty bug.
  • hashemi
    hashemi over 7 years
    Perhaps you can get rid of the precondition by making power a UInt
  • mklbtz
    mklbtz over 7 years
    And of course you can always define this as an operator (as the more popular answers suggest) or an extension to Int or you can have those things call this free function — whatever your heart desires.
  • Scott Carter
    Scott Carter almost 7 years
    In order to support chained exponentiations such as 2 ^^ 3 ^^ 4 you will need to add associativity: right to precedencegroup. This is shown in stackoverflow.com/a/39117806/1949877
  • Mahendra
    Mahendra about 6 years
    pow() is not suitable for large calculation where fractional part is also very important. For me your answer gives a hint. Thanks:)
  • claude31
    claude31 about 6 years
    pow(a, b) returns NaN if b < 0 ; so you could add a test for this : let power = (b >= 0) ? pow(a, b) : 1 / pow(a, -b) ; note that a must be declared as Decimal let a : Decimal = 2 ; let b = -3
  • mklbtz
    mklbtz almost 6 years
    Very nice! For doing this generically in Swift > 4.0 (Xcode 9.0), you'd want to use BinaryInteger. IntegerType was deprecated.
  • eharo2
    eharo2 about 5 years
    Also, the name 'calc" is too generic to be used in such a specific operation.. cal(2,2) can mean any possible calculation you want to apply to 2 numbers... 2+2, 2-2, 2*2, 2/2, 2pow2, 2root2, etc.
  • midtownguru
    midtownguru over 4 years
    This answer is the clearest with Double and Int types.
  • Vyacheslav
    Vyacheslav over 4 years
    It seems, this solution leads to a stackoverflow exception
  • ChuckZHB
    ChuckZHB almost 4 years
    That is what I want, thanks. In Python, just 3 ** 3. Sometimes, I need to solve algorithm problem using Swift, it is really painful comparing to using Python.
  • Binh Le
    Binh Le over 3 years
    Yep agree, it replaces the standard xor operator
  • Binh Le
    Binh Le over 3 years
    Time complexity would be O(n). Use bit shifting for O(1)
  • Roshan Sah
    Roshan Sah over 3 years
    @ChuckZHB do you know operator overloading?
  • Reinhard Männer
    Reinhard Männer over 2 years
    I think the 3rd line should read guard toPower < 0 else { return 0 } since n^0 = 1.
  • Stephan Januar
    Stephan Januar over 2 years
    This is a good solution, if performance comes in play. For all normal purposes the other solutions are easier to understand.
  • Vyacheslav
    Vyacheslav over 2 years
    @StephanJanuar thank you very much
  • app4g
    app4g over 2 years
    let output = pow(Decimal(movingPower),4) this was suggested by Xcode to make it into decimal