How to get the Power of some Integer in Swift language?
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.
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.
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
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)))