How to get the Power of some Integer in Swift language?
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
林鼎棋
Updated on July 09, 2020Comments
-
林鼎棋 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 almost 10 yearsIt's good practice to explain why your code offers a solution, rather than just dumping code into an answer.
-
CLRBTH over 9 yearsAnd it's far from a correct power function. What about 0 as an exponent or any negative value.
-
wjl about 9 yearsThat 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 about 9 yearsSo 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 about 9 yearsfunc ^^ (radix: Double, power: Double) -> Double { return Double(pow(Double(radix), Double(power))) }
-
Tim Arnold about 9 yearsI 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/Conceptual/… and developer.apple.com/library/ios/documentation/Swift/Conceptual/…) like so:
infix operator ^^ { precedence 160 } func ^^
... and so on -
mklbtz almost 8 yearsThis 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 almost 8 yearsTo shorten it up, you could implement this with a
reduce
call.return (2...power).reduce(base) { result, _ in result * base }
-
Vanya over 7 yearsI really like this solution, but with Swift 3 it does not work. Any idea how to make it work?
-
Cody over 7 yearsAny 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 over 7 yearsWhy would you want power for booleans? What do you mean by true x true or square root of false?
-
Cody over 7 yearsIn 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 over 7 years
func p(_ b: Bool) -> Double { return b?-1:1 }
? -
Cody over 7 yearsThanks! 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 over 7 yearsA 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 returnInt
, but give extremely different results. You’d just be begging for a nasty bug. -
hashemi over 7 yearsPerhaps you can get rid of the precondition by making power a UInt
-
mklbtz over 7 yearsAnd 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 almost 7 yearsIn 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 about 6 yearspow() is not suitable for large calculation where fractional part is also very important. For me your answer gives a hint. Thanks:)
-
claude31 about 6 yearspow(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 almost 6 yearsVery nice! For doing this generically in Swift > 4.0 (Xcode 9.0), you'd want to use
BinaryInteger
.IntegerType
was deprecated. -
eharo2 about 5 yearsAlso, 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 over 4 yearsThis answer is the clearest with Double and Int types.
-
Vyacheslav over 4 yearsIt seems, this solution leads to a stackoverflow exception
-
ChuckZHB almost 4 yearsThat 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 over 3 yearsYep agree, it replaces the standard
xor
operator -
Binh Le over 3 yearsTime complexity would be O(n). Use
bit shifting
for O(1) -
Roshan Sah over 3 years@ChuckZHB do you know operator overloading?
-
Reinhard Männer over 2 yearsI think the 3rd line should read
guard toPower < 0 else { return 0 }
since n^0 = 1. -
Stephan Januar over 2 yearsThis is a good solution, if performance comes in play. For all normal purposes the other solutions are easier to understand.
-
Vyacheslav over 2 years@StephanJanuar thank you very much
-
app4g over 2 years
let output = pow(Decimal(movingPower),4)
this was suggested by Xcode to make it into decimal