如何在Swift语言中获得一些Integer的权力?

我最近很快学习,但我有一个基本的问题,无法find答案

我想得到类似的东西

var a:Int = 3 var b:Int = 3 println( pow(a,b) ) // 27 

但pow函数只能使用double数字,它不能和integer一起工作,我甚至不能使用double(a)或a.double()等方法来将int转换为double。

为什么它不提供整数的力量? 它肯定会返回一个整数没有歧义! 为什么我不能将一个整数转换为双精度? 它只是改变3到3.0(或者30000 …不pipe)

如果我有两个整数,我想做功率操作,我该怎么做顺利?

谢谢!

如果你喜欢,你可以声明一个中infix operator来做到这一点。

 // 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 

我用了两个插入符号,所以你仍然可以使用XOR运算符 。

Swift 3的更新

在Swift 3中,“魔数”的precedenceprecedence所取代:

 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 

除此之外,你的variables声明有语法错误,这正如你所期望的那样。 您只需将其转换为Double,然后将值传递给pow。 然后,如果你正在使用2个Ints,并且你想要一个Int在操作的另一端,那么就回到Int

 import Darwin let a: Int = 3 let b: Int = 3 let x: Int = Int(pow(Double(a),Double(b))) 

一点细节更多

  infix operator ^^ { associativity left precedence 160 } func ^^ (radix: Int, power: Int) -> Int { return Int(pow(CGFloat(radix), CGFloat(power))) } 

swift – 二进制expression式

如果你对操作符重载不感兴趣(尽pipe^^解决scheme对读取你的代码的人可能是清楚的),你可以快速实现:

 let pwrInt:(Int,Int)->Int = { a,b in return Int(pow(Double(a),Double(b))) } pwrInt(3,4) // 81 

有时候,把一个Int转换成Double是不可行的。 在某种程度上,这种转换会导致精度的下降。 例如,下面的代码不会返回您可能直观地预期的内容。 (Swift 3.0)

 Double(Int.max - 1) < Double(Int.max) // false! 

如果您需要高精度的数据,而且不需要担心负指数 (无论如何不能用整数求解),那么使用尾recursion指数乘平方algorithm是最好的select。 根据这个答案 ,这是“在非对称密码学中对大数进行模幂运算的标准方法”。

 func pow(_ base: Int, _ power: Int) -> Int { func expBySq(_ y: Int, _ x: Int, _ n: Int) -> Int { precondition(n >= 0) if n == 0 { return y } else if n == 1 { return y * x } else if n % 2 == 0 { return expBySq(y, x * x, n / 2) } else { // n is odd return expBySq(y * x, x * x, (n - 1) / 2) } } return expBySq(1, base, power) } 

如果你真的想要一个'纯粹的'实现,不想强制/从Double ,你需要实现它。 这是一个微不足道的实现; 有更快的algorithm,但这将工作:

 func pow (base:Int, power:UInt) -> Int { var answer : Int = 1 for _ in 0..power { answer *= base } return answer } > pow (2, 4) $R3: Int = 16 > pow (2, 8) $R4: Int = 256 > pow (3,3) $R5: Int = 27 

在一个真正的实现中,你可能需要一些错误检查。

将答案组合成一组重载的函数(使用“**”而不是“^^”作为其他语言使用 – 对我更清楚):

 // http://stackoverflow.com/questions/24196689/how-to-get-the-power-of-some-integer-in-swift-language // Put this at file level anywhere in your project infix operator ** { associativity left precedence 160 } func ** (radix: Double, power: Double) -> Double { return pow(radix, power) } func ** (radix: Int, power: Int ) -> Double { return pow(Double(radix), Double(power)) } func ** (radix: Float, power: Float ) -> Double { return pow(Double(radix), Double(power)) } 

使用浮点数时,可能会失去精度。 如果使用数字文字以及整数和非整数的组合,则默认情况下将以Double结尾。 我个人喜欢使用mathexpression式而不是像pow(a,b)这样的function来进行风格/可读性的function,但这只是我自己。

任何会导致pow()抛出错误的运算符也会导致这些函数抛出一个错误,所以错误检查的负担仍然在于使用power函数的代码。 吻,恕我直言。

使用本地pow()函数允许例如取平方根(2 ** 0.5)或反(2 ** -3 = 1/8)。 由于可能使用反或分数指数,我写了所有的代码返回pow()函数的默认双精度types,这应该返回最高精度(如果我记得正确的文档)。 如果需要的话,可以将其input到Int或Float或其他types的内容中,可能会导致精度的下降。

 2 ** -3 = 0.125 2 ** 0.5 = 1.4142135623731 2 ** 3 = 8 

mklbtz是正确的幂乘平方是计算整数幂的标准algorithm,但algorithm的尾recursion实现似乎有点混乱。 请参阅http://www.programminglogic.com/fast-exponentiation-algorithms/通过在C中取平方的非recursion实现的指数。我试图把它翻译成Swift在这里:;

 func expo(_ base: Int, _ power: Int) -> Int { var result = 1 while (power != 0){ if (power%2 == 1){ result *= base } power /= 2 base *= base } return result } 

当然,这可以通过创build一个重载操作符来调用它,可以重写它,使其更通用,因此它可以处理任何实现IntegerType协议的东西。 为了使其通用,我可能会从类似的东西开始

  func expo<T:IntegerType>(_ base: T, _ power: T) -> T { var result : T = 1 

但是,这可能会被消除。

要不就 :

 var a:Int = 3 var b:Int = 3 println(pow(Double(a),Double(b))) 

试图结合超载,我试图使用generics,但无法使其工作。 我终于想通过使用NSNumber而不是尝试重载或使用generics。 这简化如下:

 typealias Dbl = Double // Shorter form infix operator ** {associativity left precedence 160} func ** (lhs: NSNumber, rhs: NSNumber) -> Dbl {return pow(Dbl(lhs), Dbl(rhs))} 

下面的代码和上面的代码是一样的,但是实现了错误检查来查看参数是否可以被成功转换为双精度。

 func ** (lhs: NSNumber, rhs: NSNumber) -> Dbl { // Added (probably unnecessary) check that the numbers converted to Doubles if (Dbl(lhs) ?? Dbl.NaN) != Dbl.NaN && (Dbl(rhs) ?? Dbl.NaN) != Dbl.NaN { return pow(Dbl(lhs), Dbl(rhs)) } else { return Double.NaN } } 

我更喜欢这个

 func ^ (left:NSNumber, right: NSNumber) -> NSNumber { return pow(left.doubleValue,right.doubleValue) } var a:NSNumber = 3 var b:NSNumber = 3 println( a^b ) // 27 

要计算power(2, n) ,只需使用:

 let result = 2 << (n-1) 
  func calc (base:Int, number:Int) -> Int { var answer : Int = base for _ in 2...number {answer *= base } return answer } calc (2,2)