Exponentiation operator in Swift

69,522

Solution 1

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

Solution 2

If you happen to be raising 2 to some power, you can use the bitwise left shift operator:

let x = 2 << 0    // 2
let y = 2 << 1    // 4
let z = 2 << 7    // 256

Notice that the 'power' value is 1 less than you might think.

Note that this is faster than pow(2.0, 8.0) and lets you avoid having to use doubles.

Solution 3

For anyone looking for a Swift 3 version of the ** infix operator:

precedencegroup ExponentiationPrecedence {
  associativity: right
  higherThan: MultiplicationPrecedence
}

infix operator ** : ExponentiationPrecedence

func ** (_ base: Double, _ exp: Double) -> Double {
  return pow(base, exp)
}

func ** (_ base: Float, _ exp: Float) -> Float {
  return pow(base, exp)
}

2.0 ** 3.0 ** 2.0    // 512
(2.0 ** 3.0) ** 2.0  // 64

Solution 4

Swift 4.2

import Foundation

var n = 2.0 // decimal
var result = 5 * pow(n, 2)
print(result)
// 20.0

Solution 5

I did it like so:

operator infix ** { associativity left precedence 200 }

func ** (base: Double, power: Double) -> Double {
    return exp(log(base) * power)
}
Share:
69,522
mcgregor94086
Author by

mcgregor94086

Serial entrepreneur and co-founder of high tech companies. Consultant and coach to entrepreneurs.

Updated on July 08, 2022

Comments

  • mcgregor94086
    mcgregor94086 almost 2 years

    I don't see an exponentiation operator defined in the base arithmetic operators in the Swift language reference.

    Is there really no predefined integer or float exponentiation operator in the language?

  • Kevin
    Kevin almost 10 years
    Better to use **, so you can use it on ints and not conflict with XOR.
  • Kostiantyn Koval
    Kostiantyn Koval over 9 years
    ^ operator is define as XOR in Swift.
  • Chris
    Chris about 9 years
    This is nice as far as it goes, but doesn't really answer the question.
  • Daniel Farrell
    Daniel Farrell about 9 years
    Warning! There is a problem here. For example, usually in programming languages, -2.0**2.0 = -(2.0**2.0) = -4.0. However, here -2.0**2.0 = (-2.0)**2.0 = 4.0, which might not be the intended use and could causes quite a nasty and hard to track down bug.
  • dldnh
    dldnh over 8 years
    I was interested in powers of two, so it answered it for me.
  • beepscore
    beepscore over 8 years
    @chanceoperation Alternatively, for 2 to the power of n you can shift 1 or 0b00000001 to the left by n places Swift Advanced Operators let x = 0b00000001 << exponent // 2**exponent let x = 1 << 0 // 1 let x = 1 << 2 // 4 let x = 1 << 8 // 256
  • Omegaman
    Omegaman almost 8 years
    NSHipster uses a similar description but with a precedence of 160 to match << and >>. Different precedences will lead to different code interpretations, so standardizing on a precedence for common operators is important. I don't know what the best standard is, but giving << 2 and ** 2 the same precedence makes some sense. nshipster.com/swift-operators
  • vwvan
    vwvan over 7 years
    Isn't exponentiation right associative? en.wikipedia.org/wiki/Operator_associativity
  • iainH
    iainH about 7 years
    Nice. Don't forget to import Darwin to get pow
  • brandonscript
    brandonscript over 6 years
    Pretty sure the associativity should be left, not right. 2^3^2 is 64, not 512.
  • sam-w
    sam-w about 5 years
    this seems... inefficient
  • Ray Toal
    Ray Toal over 4 years
    Well, in both Python and JavaScript 2**3**2 is 512, not 64. I don't know any programming language with a left-associative exponentiation operator. They're all right-associative. If you implement this in Swift, you should definitely do it right-associative to be consistent with other popular languages, as well as mathematical convention.
  • ReinstateMonica3167040
    ReinstateMonica3167040 over 3 years
    In more recent Swift versions, the first line should be: infix operator ** : BitwiseShiftPrecedence
  • Barry Jones
    Barry Jones over 2 years
    This function fails to pass test cases. What’s the correct behavior for exponents that are negative? It seems this pow function would round them all up to 1, which might be acceptable until the base is also negative, e.g. -1**-1 = -1, -10**-1 = -0.1.
  • Barry Jones
    Barry Jones over 2 years
    The correct behavior for negative powers is probably to match what you’d get from casting the pow(Double, Double) result as an Int. I’ve provided a new answer with that solution, but also optimizing for speed by handling boundary cases and using the bitwise left shift operator for powers of 2 and -2.
  • Barry Jones
    Barry Jones over 2 years
    You should be doing 1 << exponent, because you’re literally moving the bit left on a small endian value. 1 << 1 == 2, or imagine 00000001 gets the bit shifted left 1, giving 00000010, which is 2 in binary. I like this solution though. I incorporated it into my comprehensive answer below.