How to get the Power of some Integer in Swift lang

2019-01-31 05:50发布

I'm learning swift recently, but I have a basic problem that can't find an answer

I want to get something like

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

but the pow function can work with double number only, it doesn't work with integer, and I can't even cast the int to double by something like Double(a) or a.double()...

Why it doesn't supply the power of integer? it will definitely return an integer without ambiguity ! and Why I can't cast a integer to a double? it just change 3 to 3.0 (or 3.00000... whatever)

if I got two integer and I want to do the power operation, how can I do it smoothly?

Thanks!

15条回答
劳资没心,怎么记你
2楼-- · 2019-01-31 06:00

Sometimes, casting an Int to a Double is not a viable solution. At some magnitudes there is a loss of precision in this conversion. For example, the following code does not return what you might intuitively expect. (Swift 3.0)

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

If you need precision at high magnitudes and don't need to worry about negative exponents — which can't be generally solved with integers anyway — then this implementation of the tail-recursive exponentiation-by-squaring algorithm is your best bet. According to this SO answer, this is "the standard method for doing modular exponentiation for huge numbers in asymmetric cryptography."

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) 
}
查看更多
地球回转人心会变
3楼-- · 2019-01-31 06:02

Swift 4.x version

precedencegroup ExponentiationPrecedence {
  associativity: right
  higherThan: MultiplicationPrecedence
}

infix operator ^^: ExponentiationPrecedence
public func ^^ (radix: Float, power: Float) -> Float {
  return pow((radix), (power))
}

public func ^^ (radix: Double, power: Double) -> Double {
  return pow((radix), (power))
}

public func ^^ (radix: Int, power: Int) -> Int {
  return NSDecimalNumber(decimal: pow(Decimal(radix), power)).intValue
}
查看更多
戒情不戒烟
4楼-- · 2019-01-31 06:04

It turns out you can also use pow(). For example, you can use the following to express 10 to the 9th.

pow(10, 9)

Along with pow, powf() returns a float instead of a double. I have only tested this on Swift 4 and macOS 10.13.

查看更多
手持菜刀,她持情操
5楼-- · 2019-01-31 06:07

mklbtz is correct about exponentiation by squaring being the standard algorithm for computing integer powers, but the tail-recursive implementation of the algorithm seems a bit confusing. See http://www.programminglogic.com/fast-exponentiation-algorithms/ for a non-recursive implementation of exponentiation by squaring in C. I've attempted to translate it to Swift here:

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
}

Of course, this could be fancied up by creating an overloaded operator to call it and it could be re-written to make it more generic so it worked on anything that implemented the IntegerType protocol. To make it generic, I'd probably start with something like

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

But, that is probably getting carried away.

查看更多
放我归山
6楼-- · 2019-01-31 06:07

Or just :

var a:Int = 3
var b:Int = 3
println(pow(Double(a),Double(b)))
查看更多
闹够了就滚
7楼-- · 2019-01-31 06:09

little detail more

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

swift - Binary Expressions

查看更多
登录 后发表回答