141

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!

林鼎棋
  • 1,995
  • 2
  • 16
  • 25
  • These type declarations are wrong –  Jun 13 '14 at 02:19
  • most languages don't have an integer power function due to [this reason](https://stackoverflow.com/q/2398442/995714) – phuclv Oct 06 '17 at 02:05
  • 1
    @phuclv's note points to a great discussion on the topic. I would change the text in the link to "these reasons" – eharo2 May 20 '19 at 16:49
  • Hint: (^) is the The bitwise XOR operator, or “exclusive OR operator”. In case you wondered what your code was doing before you came here. – mrk Dec 19 '20 at 13:30

20 Answers20

98

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
Grimxn
  • 22,115
  • 10
  • 72
  • 85
  • 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 Apr 17 '15 at 01:04
  • func ^^ (radix: Double, power: Double) -> Double { return Double(pow(Double(radix), Double(power))) } – padapa Apr 17 '15 at 01:20
  • 3
    I found this didn't quite behave as I expected because the precedence was off. For an exponentiative operator, set precedence to 160 (see https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/doc/uid/TP40014097-CH32-ID383 and https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html) like so: `infix operator ^^ { precedence 160 } func ^^`... and so on – Tim Arnold May 26 '15 at 02:34
  • I really like this solution, but with Swift 3 it does not work. Any idea how to make it work? – Vanya Sep 19 '16 at 18:51
  • 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. – Cody Sep 21 '16 at 23:04
  • Why would you want power for booleans? What do you mean by true x true or square root of false? – Grimxn Sep 22 '16 at 07:14
  • 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. – Cody Sep 23 '16 at 00:52
  • 1
    `func p(_ b: Bool) -> Double { return b?-1:1 }` ? – Grimxn Sep 23 '16 at 05:50
  • 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! – Cody Sep 23 '16 at 20:08
  • 1
    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. – Adam Kaplan Dec 11 '16 at 21:32
  • In order to support chained exponentiations such as 2 ^^ 3 ^^ 4 you will need to add associativity: right to precedencegroup. This is shown in https://stackoverflow.com/a/39117806/1949877 – Scott Carter Jun 15 '17 at 02:43
88

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)))
Keara
  • 589
  • 1
  • 6
  • 17
Mick MacCallum
  • 129,200
  • 40
  • 280
  • 281
18

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.

mklbtz
  • 773
  • 7
  • 17
  • 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. – mklbtz Feb 07 '17 at 16:26
  • It seems, this solution leads to a stackoverflow exception – Vyacheslav Feb 08 '20 at 21:29
16

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.

GoZoner
  • 67,920
  • 20
  • 95
  • 145
  • 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 Aug 18 '16 at 14:00
  • 4
    To shorten it up, you could implement this with a `reduce` call. `return (2...power).reduce(base) { result, _ in result * base }` – mklbtz Aug 18 '16 at 14:00
  • 1
    Perhaps you can get rid of the precondition by making power a UInt – hashemi Feb 06 '17 at 14:47
10

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
2.pow(toPower: 0) // returns 1
Cœur
  • 37,241
  • 25
  • 195
  • 267
j_thompson
  • 201
  • 2
  • 3
8

To calculate power(2, n), simply use:

let result = 1 << n
kaushal
  • 1,553
  • 18
  • 25
Binh Le
  • 486
  • 5
  • 12
5

If you're disinclined towards operator overloading (although the ^^ solution is probably clear to someone reading your code) you can do a quick implementation:

let pwrInt:(Int,Int)->Int = { a,b in return Int(pow(Double(a),Double(b))) }
pwrInt(3,4) // 81
HenryRootTwo
  • 2,572
  • 1
  • 27
  • 27
5

It turns out you can also use pow(). For example, you can use the following to express 10 to the 9th.

pow(10, 9)

Along with pow, powf() returns a float instead of a double. I have only tested this on Swift 4 and macOS 10.13.

Jake3231
  • 703
  • 8
  • 22
  • 1
    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 – claude31 May 12 '18 at 08:24
  • ```let output = pow(Decimal(movingPower),4)``` this was suggested by Xcode to make it into decimal – app4g Feb 12 '22 at 01:14
4

little detail more

   infix operator ^^ { associativity left precedence 160 }
   func ^^ (radix: Int, power: Int) -> Int {
       return Int(pow(CGFloat(radix), CGFloat(power)))
   }

swift - Binary Expressions

tylyo
  • 572
  • 5
  • 16
4

mklbtz is correct about exponentiation by squaring being the standard algorithm for computing integer powers, but the tail-recursive implementation of the algorithm seems a bit confusing. See http://www.programminglogic.com/fast-exponentiation-algorithms/ for a non-recursive implementation of exponentiation by squaring in C. I've attempted to translate it to Swift here:

func expo(_ base: Int, _ power: Int) -> Int {
    var result = 1

    while (power != 0){
        if (power%2 == 1){
            result *= base
        }
        power /= 2
        base *= base
    }
    return result
}

Of course, this could be fancied up by creating an overloaded operator to call it and it could be re-written to make it more generic so it worked on anything that implemented the IntegerType protocol. To make it generic, I'd probably start with something like

    func expo<T:IntegerType>(_ base: T, _ power: T) -> T {
    var result : T = 1

But, that is probably getting carried away.

Paul Buis
  • 805
  • 7
  • 7
  • 1
    Very nice! For doing this generically in Swift > 4.0 (Xcode 9.0), you'd want to use [`BinaryInteger`](https://developer.apple.com/documentation/swift/binaryinteger). `IntegerType` was deprecated. – mklbtz Jun 26 '18 at 14:29
3

Or just :

var a:Int = 3
var b:Int = 3
println(pow(Double(a),Double(b)))
Fafa
  • 93
  • 8
3

Combining the answers into an overloaded set of functions (and using "**" instead of "^^" as some other languages use - clearer to me):

// http://stackoverflow.com/questions/24196689/how-to-get-the-power-of-some-integer-in-swift-language
// Put this at file level anywhere in your project
infix operator ** { associativity left precedence 160 }
func ** (radix: Double, power: Double) -> Double { return pow(radix, power) }
func ** (radix: Int,    power: Int   ) -> Double { return pow(Double(radix), Double(power)) }
func ** (radix: Float,  power: Float ) -> Double { return pow(Double(radix), Double(power)) }

When using Float, you may lose precision. If using numeric literals and a mix of integers and non-integers, you will end up with Double by default. I personally like the ability to use a mathematical expression instead of a function like pow(a, b) for stylistic/readability reasons, but that's just me.

Any operators that would cause pow() to throw an error will also cause these functions to throw an error, so the burden of error checking still lies with the code using the power function anyway. KISS, IMHO.

Using the native pow() function allows to eg take square roots (2 ** 0.5) or inverse (2 ** -3 = 1/8). Because of the possibility to use inverse or fractional exponents, I wrote all my code to return the default Double type of the pow() function, which should return the most precision (if I remember the documentation correctly). If needed, this can be type-casted down to Int or Float or whatever, possibly with the loss of precision.

2 ** -3  = 0.125
2 ** 0.5 = 1.4142135623731
2 ** 3   = 8
Eric Aya
  • 69,473
  • 35
  • 181
  • 253
ECJB
  • 59
  • 3
  • pow() is not suitable for large calculation where fractional part is also very important. For me your answer gives a hint. Thanks:) – Mahendra Mar 16 '18 at 09:17
2

Array(repeating: a, count: b).reduce(1, *)

Roman
  • 1,309
  • 14
  • 23
2

Swift 5

I was surprised, but I didn't find a proper correct solution here.

This is mine:

enum CustomMath<T: BinaryInteger> {

    static func pow(_ base: T, _ power: T) -> T {
        var tempBase = base
        var tempPower = power
        var result: T = 1

        while (tempPower != 0) {
            if (tempPower % 2 == 1) {
                result *= tempBase
            }
            tempPower = tempPower >> 1
            tempBase *= tempBase
        }
        return result
    }
}

Example:

CustomMath.pow(1,1)
aepryus
  • 4,715
  • 5
  • 28
  • 41
Vyacheslav
  • 26,359
  • 19
  • 112
  • 194
1

Swift 4.x version

precedencegroup ExponentiationPrecedence {
  associativity: right
  higherThan: MultiplicationPrecedence
}

infix operator ^^: ExponentiationPrecedence
public func ^^ (radix: Float, power: Float) -> Float {
  return pow((radix), (power))
}

public func ^^ (radix: Double, power: Double) -> Double {
  return pow((radix), (power))
}

public func ^^ (radix: Int, power: Int) -> Int {
  return NSDecimalNumber(decimal: pow(Decimal(radix), power)).intValue
}
Noah Wilder
  • 1,656
  • 20
  • 38
Mahendra
  • 8,448
  • 3
  • 33
  • 56
1

In Swift 5:

extension Int{
    func expo(_ power: Int) -> Int {
        var result = 1
        var powerNum = power
        var tempExpo = self
        while (powerNum != 0){
        if (powerNum%2 == 1){
            result *= tempExpo
        }
        powerNum /= 2
        tempExpo *= tempExpo
        }
        return result
    }
}

Use like this

2.expo(5) // pow(2, 5)

Thanks to @Paul Buis's answer.

dengST30
  • 3,643
  • 24
  • 25
1

An Int-based pow function that computes the value directly via bit shift for base 2 in Swift 5:

func pow(base: Int, power: UInt) -> Int {
    if power == 0 { return 1 }
    // for base 2, use a bit shift to compute the value directly
    if base == 2 { return 2 << Int(power - 1) }
    // otherwise multiply base repeatedly to compute the value
    return repeatElement(base, count: Int(power)).reduce(1, *)
}

(Make sure the result is within the range of Int - this does not check for the out of bounds case)

Ralf Ebert
  • 3,556
  • 3
  • 29
  • 43
0

Trying to combine the overloading, I tried to use generics but couldn't make it work. I finally figured to use NSNumber instead of trying to overload or use generics. This simplifies to the following:

typealias Dbl = Double // Shorter form
infix operator ** {associativity left precedence 160}
func ** (lhs: NSNumber, rhs: NSNumber) -> Dbl {return pow(Dbl(lhs), Dbl(rhs))}

The following code is the same function as above but implements error checking to see if the parameters can be converted to Doubles successfully.

func ** (lhs: NSNumber, rhs: NSNumber) -> Dbl {
    // Added (probably unnecessary) check that the numbers converted to Doubles
    if (Dbl(lhs) ?? Dbl.NaN) != Dbl.NaN && (Dbl(rhs) ?? Dbl.NaN) != Dbl.NaN {
        return pow(Dbl(lhs), Dbl(rhs))
    } else {
        return Double.NaN
    }
}
ECJB
  • 59
  • 3
-3

I like this better

func ^ (left:NSNumber, right: NSNumber) -> NSNumber {
    return pow(left.doubleValue,right.doubleValue)
}
var a:NSNumber = 3
var b:NSNumber = 3 
println( a^b ) // 27
Pang
  • 9,564
  • 146
  • 81
  • 122
  • 3
    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. – wjl Mar 25 '15 at 20:08
  • Yep agree, it replaces the standard `xor` operator – Binh Le Oct 05 '20 at 01:37
-5
func calc (base:Int, number:Int) -> Int {
    var answer : Int = base
    for _ in 2...number {answer *= base } 
    return answer
}

Example:

calc (2,2)
benc
  • 1,381
  • 5
  • 31
  • 39
  • 1
    It's good practice to explain why your code offers a solution, rather than just dumping code into an answer. – Rudi Kershaw Jul 24 '14 at 15:28
  • 1
    And it's far from a correct power function. What about 0 as an exponent or any negative value. – macbirdie Nov 13 '14 at 14:00
  • 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. – eharo2 May 20 '19 at 17:12
  • Time complexity would be O(n). Use `bit shifting` for O(1) – Binh Le Oct 05 '20 at 01:40
  • @BinhLe bit shifting only works if base is 2. For example 3^2 = 9 but 3 << 2 is 12. – HangarRash Aug 29 '23 at 17:48