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
Swift Error: Missing Return in a Function Expected to Return 'String'
Autolayout Contraints for a View from Xib
Skphysicsbody Avoid Collision Swift/Spritekit
Does a Mutating Struct Function in Swift Create a New Copy of Self
Firestore Order by Time But Sort by Id
Initialize Lazy Instance Variable with Value That Depends on Other Instance Variables
Why am I Allowed Method Access Less Restrictive Than Class Access
Unexpectedly Large Realm File Size
Why Can't I Use a Tuple Constant as a Case in a Switch Statement
Converting a C-Style for Loop That Uses Division for the Step to Swift 3
Know When an Iteration Over Array with Async Method Is Finished
Is This a Good Way to Display Asynchronous Data
How to Write a Function That Will Unwrap a Generic Property in Swift Assuming It Is an Optional Type
Parameters After Opening Bracket
How to Convert Between Related Types Through a Common Initializer
Argument Labels Do Not Match Any Available Overloads
Beginner Swift Sprite Kit - Node Collision Detection Help (Skphysicscontact)
How to Copy a Struct and Modify One of Its Properties at the Same Time