Exponentiation operator in Swift

后端 未结 9 1160
天命终不由人
天命终不由人 2020-12-13 22:45

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 ex

相关标签:
9条回答
  • 2020-12-13 23:26

    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
    
    0 讨论(0)
  • 2020-12-13 23:31

    Swift 4.2

    import Foundation
    
    var n = 2.0 // decimal
    var result = 5 * pow(n, 2)
    print(result)
    // 20.0
    
    0 讨论(0)
  • 2020-12-13 23:32

    There isn't one but you have the pow function.

    0 讨论(0)
  • 2020-12-13 23:36

    An alternative answer is to use NSExpression

    let mathExpression = NSExpression(format:"2.5**2.5")
    let answer = mathExpression.expressionValue(with: nil, context: nil) as? Double
    

    or

    let mathExpression = NSExpression(format:"2**3")
    let answer = mathExpression.expressionValue(with: nil, context: nil) as? Int
    
    0 讨论(0)
  • 2020-12-13 23:38

    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.

    0 讨论(0)
  • 2020-12-13 23:38

    If you're specifically interested in the exponentiation operator for Int type, I don't think that existing answers would work particularly well for large numbers due to the way how floating point numbers are represented in memory. When converting to Float or Double from Int and then back (which is required by pow, powf and powl functions in Darwin module) you may lose precision. Here's a precise version for Int:

    let pow = { Array(repeating: $0, count: $1).reduce(1, *) }
    

    Note that this version isn't particularly memory efficient and is optimized for source code size.

    Another version that won't create an intermediate array:

    func pow(_ x: Int, _ y: Int) -> Int {
      var result = 1
      for i in 0..<y {
        result *= x
      }
      return result
    }
    
    0 讨论(0)
提交回复
热议问题