## How do I make my exponentiation operator work with all numeric types in Swift?

Here is a more type-safe implementation, using operator overloading. For integer types,

you can define `^^`

as

`infix operator ^^ { associativity left precedence 170 }`

func ^^<T : IntegerType, U : IntegerType> (base: T, var power: U) -> T {

if power < 0 { return 0 }

var result : T = 1

var square : T = base

if power > 0 {

if power % 2 == 1 { result *= square }

power /= 2

}

while power > 0 {

square *= square

if power % 2 == 1 { result *= square }

power /= 2

}

return result

}

(I have chosen a more efficient variant called "exponentiation by repeated squaring and multiplication".)

For floating point types, define a protocol the covers all types that can be

converted from and to `Double`

:

`protocol DoubleConvertible {`

init(_ value: Double)

var doubleValue : Double { get }

}

and make `Float`

, `Double`

and `CGFloat`

conform to that protocol:

`extension Double : DoubleConvertible {`

var doubleValue : Double { return self }

}

extension Float : DoubleConvertible {

var doubleValue : Double { return Double(self) }

}

extension CGFloat : DoubleConvertible {

var doubleValue : Double { return Double(self) }

}

Now the floating point exponentiation can simply be defined as

`func ^^<T : DoubleConvertible, U:DoubleConvertible> (base: T, power: U) -> T {`

return T(pow(base.doubleValue, power.doubleValue))

}

Examples:

`let x1 = 2^^3 // Int`

let x2 = UInt64(2)^^3 // UInt64

let x3 = 2.0 ^^ 3 // Double

let x4 = Float(2.0) ^^ 3 // Float

let x5 = "a" ^^ "b" // Compiler error

**Update for Swift 4:**

`IntegerType`

has become `BinaryInteger`

(SE-0104 Protocol-oriented integers) and

the syntax for declaring operators has changed

(SE-0077 Improved operator declarations.)

Here is an implementation for all integer and floating point

bases with `Int`

exponents:

`precedencegroup ExponentiationPrecedence { associativity: right higherThan: MultiplicationPrecedence }`

infix operator ^^: ExponentiationPrecedence

func ^^<T : BinaryInteger>(base: T, power: Int) -> T {

if power < 0 { return 0 }

var power = power

var result: T = 1

var square = base

if power > 0 {

if power % 2 == 1 { result *= square }

power /= 2

}

while power > 0 {

square *= square

if power % 2 == 1 { result *= square }

power /= 2

}

return result

}

func ^^(base: Float, power: Int) -> Float {

return pow(base, Float(power))

}

func ^^(base: Double, power: Int) -> Double {

return pow(base, Double(power))

}

func ^^(base: CGFloat, power: Int) -> CGFloat {

return pow(base, CGFloat(power))

}

Examples:

`let x1 = 2^^3 // Int`

let x2 = UInt64(2)^^3 // UInt64

let x3 = 2.0 ^^ -3 // Double

let x4 = Float(2.0) ^^ 3 // Float

// let x6 = "a" ^^ 5 // Compiler error

See SE-0104 Protocol-oriented integers

about the new protocol hierarchy introduced in Swift 4.

## Exponentiation operator in Swift

There isn't an operator but you can use the pow function like this:

`return pow(num, power)`

If you want to, you could also make an operator call the pow function like this:

`infix operator ** { associativity left precedence 170 }`

func ** (num: Double, power: Double) -> Double{

return pow(num, power)

}

2.0**2.0 //4.0

## Swift How combine to Numeric Type

You don't have to re-invent the wheel, there is already protocol which you need: `Numeric`

.

Its description is very self-descriptive:

A type with values that support multiplication

And the types like `Int`

, `Double`

, ... already conform to it.

Anyway, if you wonder why your code doesn't work, it's because protocol provides interface and tells what implementations should contain and what is possible to do with them.

So, if you need that your `Number`

s can be multiplied, you need to describe it in protocol's declaration.

`protocol Number {`

static func * (lhs: Self, rhs: Self) -> Self

}

... now you described that every `Number`

can be multiplied by other `Number`

. /p>

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

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

## How can I raise all the elements in an int array by a power of 3 in Swift?

You can use **map()** and **pow()** together:

`import Foundation`

let nums = [1, 2, 3, 4, 5, 6]

let cubes = nums.map { Int(pow(Double($0), 3)) }

let raisedBySix = nums.map { Int(pow(Double($0), 6)) }

print(cubes) // [1, 8, 27, 64, 125, 216]

print(raisedBySix) // [1, 64, 729, 4096, 15625, 46656]

## Swift's pow() function won't accept Doubles as arguments

why is it complaining about this?

Because pow returns `Double`

. And `Double`

is not identical to `T`

. The error message is misleading, but it means "Cannot find `pow`

that accepts `(Double, Double)`

and returns `T`

type"

I think you are misunderstanding "cast" in Swift. In Swift `as`

does not convert numeric types.

`let intVal:Int = 12`

let doubleVal:Double = intVal as Double

// ^ [!] error: 'Int' is not convertible to 'Double'

And If the type of operand is not predictable at compile time, invalid casting causes runtime error:

`func foo<T: IntegerLiteralConvertible>(x: T) {`

x as Double // <-- Execution was interrupted

}

foo(12 as Int)

Instead, we must explicitly "convert" them. see the document: Numeric Type Conversion

`let intVal:Int = 12`

let doubleVal:Double = Double(intVal)

This works only because `Double`

has `init(_ v: Int)`

initializer. The following code does not compile:

`func foo<T: IntegerLiteralConvertible>(x: T) {`

Double(x)

// ^~~~~~~~~ [!] error: cannot invoke 'init' with an argument of type 'T'

}

Because `Double`

does not have `init<T:IntegerLiteralConvertible>(_ val:T)`

initializer.

So, if you want to use `pow()`

, you must convert `T`

to `Double`

for arguments, and convert `Double`

to `T`

for returning value. And there is no simple solution for that.

### Related Topics

What Does the Dollar Sign Do in Swift/Swiftui

Can Swift Return Value from an Async Void-Returning Block

Tabview Resets Navigation Stack When Switching Tabs

First Item in a List Is Always Selected

What Is Difference Between Optional and Decodeifpresent When Using Decodable For Json Parsing

How Does Collisionbitmask Work? Swift/Spritekit

How to Remove the Left and Right Padding of a List in Swiftui

Swift 4 Decodable - Dictionary With Enum as Key

How to Convert a Decimal Number to Binary in Swift

Nsattributedstring, Change the Font Overall But Keep All Other Attributes

How Flatmap API Contract Transforms Optional Input to Non Optional Result

How to See Which Version of Swift I'M Using

Go to a New View Using Swiftui

Wait Until Swift For Loop With Asynchronous Network Requests Finishes Executing

"Classname Has No Member Functionname" When Adding Uibutton Target