Exponentiation Operator in Swift

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

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.

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 to declare exponent/power operator with new precedencegroup in Swift 3?

Your code already compiles and runs – you don't need to define a precedence relationship or an associativity if you're simply using the operator in isolation, such as in the example you gave:

10 ^^ -12
10 ^^ -24

However, if you want to work with other operators, as well as chaining together multiple exponents, you'll want to define a precedence relationship that's higher than the MultiplicationPrecedence and a right associativity.

precedencegroup ExponentiativePrecedence {
associativity: right
higherThan: MultiplicationPrecedence
}

Therefore the following expression:

let x = 2 + 10 * 5 ^^ 2 ^^ 3

will be evaluated as:

let x = 2 + (10 * (5 ^^ (2 ^^ 3)))
// ^^ ^^ ^^--- Right associativity
// || \--------- ExponentiativePrecedence > MultiplicationPrecedence
// \--------------- MultiplicationPrecedence > AdditionPrecedence,
// as defined by the standard library

The full list of standard library precedence groups is available on the evolution proposal.

Using `**` as exponentiation operator in swift working incorrectly with the `-` operator

I believe your problem is:

Unary operators in Swift always take precedence over binary operators.

Here's the source: https://medium.com/swift-programming/facets-of-swift-part-5-custom-operators-1080bc78ccc

Therefore, the expression is always evaluated as (-x)**2 instead of -(x**2), since - is a unary operator and ** is a binary operator.

Defining Exponent operator

You have to import the module where the function pow is defined:

import Foundation

How to use ** for exponents using @infix func **( )?

You need to declare the operator before defining the function, as follows:

In Swift 2:

import Darwin

infix operator ** {}

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

println(8.0 ** 3.0) // works

In Swift 3:

import Darwin

infix operator **

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

print(8.0 ** 3.0) // works

Swift: generic power function as infix operator

You cannot "generalize" it. You have to implement it for each type separately.

If you look in the Swift header, you will see that that is exactly what Swift itself does for the built-in operators such as +. There is no "general" + function; there is one + function for every numeric type.

Thus:

infix operator ^^ { associativity left precedence 160 }
func ^^ (radix: Int, power: Int) -> Int {
return Int(pow(CGFloat(radix), CGFloat(power)))
}
func ^^ (radix: Double, power: Double) -> Double {
return Double(pow(CGFloat(radix), CGFloat(power)))
}
// ... and so on for as many types as you like ...

How to use pow() in Swift 3 and get an Int

Int does not have an initializer taking Decimal, so you cannot convert Decimal to Int directly with an initializer syntax like Int(...).

You can use pow(Decimal, Int) like this:

let lootBase = Int(pow((Decimal(level + 1)), 3) * 2 as NSDecimalNumber)
let lootMod = Int(pow(Decimal(level), 2) * 2 as NSDecimalNumber)

let value = Int(arc4random_uniform(UInt32(lootBase))) + lootMod

Or else, you can use pow(Double, Double) like this:

let lootBase = Int(pow((Double(level + 1)), 3) * 2)
let lootMod = Int(pow(Double(level), 2) * 2)

let value = Int(arc4random_uniform(UInt32(lootBase))) + lootMod

But, if you only calculate an integer value's power to 2 or 3, both pow(Decimal, Int) and pow(Double, Double) are far from efficient.

You can declared a simple functions like squared or cubed like this:

func squared(_ val: Int) -> Int {return val * val}
func cubed(_ val: Int) -> Int {return val * val * val}

and use them instead of pow(..., 2) or pow(..., 3):

let lootBase = cubed(level + 1) * 2
let lootMod = squared(level) * 2

let value = Int(arc4random_uniform(UInt32(lootBase))) + lootMod

(Assuming level is an Int.)



Related Topics



Leave a reply



Submit