Swift中的幂运算符


Answers:


95

没有操作员,但是您可以使用pow函数,如下所示:

return pow(num, power)

如果愿意,还可以让操作员像这样调用pow函数:

infix operator ** { associativity left precedence 170 }

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

2.0**2.0 //4.0

最好使用**,因此您可以在整数上使用它,而不会与XOR冲突。
凯文(Kevin)

3
^运算符在Swift中定义为XOR。
Kostiantyn Koval 2014年

20
警告!这里有问题。例如,通常使用编程语言 -2.0**2.0 = -(2.0**2.0) = -4.0。但是,这里-2.0**2.0 = (-2.0)**2.0 = 4.0可能不是预期的用途,并且可能导致非常讨厌且难以跟踪的错误。
丹尼尔·法瑞尔

NSHipster使用类似的描述,但优先级为160匹配<<>>。不同的优先级将导致不同的代码解释,因此,标准化通用运算符的优先级非常重要。我不知道最好的标准是什么,但给人<< 2** 2相同的优先级有一定的道理。 nshipster.com/swift-operators
Omegaman '16

8
幂运算不是关联的吗?en.wikipedia.org/wiki/Operator_associativity
vwvan

28

如果碰巧将2提高到一定的幂,则可以使用按位左移运算符:

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

注意,“ power”值比您想象的小1。

请注意,这比执行速度更快,pow(2.0, 8.0)并且可以避免使用双精度。


2
就目前而言,这很好,但是并不能真正回答问题。
克里斯

1
我对2的幂感兴趣,因此它为我解答了。
dldnh 2015年

@chanceoperation另外,对于2的n次方,您可以将1或0b00000001左移n位 let x = 0b00000001 << exponent // 2**exponent let x = 1 << 0 // 1 let x = 1 << 2 // 4 let x = 1 << 8 // 256
。Swift

13

对于正在寻找Swift 3版本的用户 **infix运算符的用户:

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

5
真好 别忘了import Darwin得到pow
iainH'Mar 31'31

3
可以肯定的是,关联性应该为左,而不是右。2 ^ 3 ^ 2是64,而不是
512。– brandonscript

嗯,在Python和JavaScript中2**3**2都是512,而不是64。我不知道任何编程语言都带有左联想指数运算符。它们都是右关联的。如果您在Swift中实现此功能,那么您绝对应该正确关联它,以使其与其他流行语言以及数学惯例保持一致。
雷·托尔

5

我这样做是这样的:

operator infix ** { associativity left precedence 200 }

func ** (base: Double, power: Double) -> Double {
    return exp(log(base) * power)
}

这似乎...效率低下
sam-w


3

斯威夫特4.2

import Foundation

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

2

如果您对Int类型的幂运算符特别感兴趣,我认为由于内存中浮点数的表示方式,现有答案对于大数不会特别有效。当转换到FloatDoubleInt,然后返回(这是由需要powpowfpowl功能Darwin模块)可能会丢失精度。这是用于的精确版本Int

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

请注意,此版本的内存使用效率不是特别高,并且已针对源代码大小进行了优化。

不会创建中间数组的另一个版本:

func pow(_ x: Int, _ y: Int) -> Int {
  var result = 1
  for i in 0..<y {
    result *= x
  }
  return result
}


0

一个替代的答案是使用NSExpression

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

要么

let mathExpression = NSExpression(format:"2**3")
let answer = mathExpression.expressionValue(with: nil, context: nil) as? Int
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.