如何在Swift语言中获得某些Integer的强大功能?

林鼎棋*_*林鼎棋 88 double integer pow swift

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

我想得到类似的东西

var a:Int = 3
var b:Int = 3 
println( pow(a,b) ) // 27
Run Code Online (Sandbox Code Playgroud)

但pow函数只能使用double数,它不能用整数运算,我甚至无法通过Double(a)或a.double()等函数将int转换为double.

为什么它不提供整数的幂?它肯定会返回一个没有歧义的整数!为什么我不能将整数转换为double?它只是改变3到3.0(或3.00000 ...无论如何)

如果我有两个整数并且我想进行电源操作,我该怎样才能顺利完成?

谢谢!

Gri*_*mxn 73

如果你愿意,你可以宣布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
Run Code Online (Sandbox Code Playgroud)

我使用了两个插入符号,因此您仍然可以使用XOR运算符.

Swift 3的更新

在Swift 3中,"神奇数字" precedence被替换为precedencegroups:

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
Run Code Online (Sandbox Code Playgroud)

  • 我发现这并不像我预期的那样,因为优先权已经取消.对于操作者exponentiative,设置优先级,以160(参见https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Expressions.html#//apple_ref/doc/uid/TP40014097-CH32-ID383和https://developer.apple.com/library/ios/documentation/Swift/Conceptual/Swift_Programming_Language/Declarations.html),像这样:`管道符^^ {优先} 160 FUNC ^^`...等等 (3认同)

Mic*_*lum 47

除此之外,您的变量声明有语法错误,这完全符合您的预期.您所要做的就是转换为Double,并将值传递给pow.然后,如果您正在使用2个Int,并且您希望在操作的另一侧返回Int,则只需返回Int

import Darwin 

let a: Int = 3
let b: Int = 3

let x: Int = Int(pow(Double(a),Double(b)))
Run Code Online (Sandbox Code Playgroud)

  • 这就是我想要的,谢谢。在 Python 中,只是“3 ** 3”。有时,我需要使用 Swift 解决算法问题,与使用 Python 相比,这真的很痛苦。 (3认同)
  • 对于 Double 和 Int 类型,这个答案是最清楚的。 (2认同)

mkl*_*btz 10

有时,铸造IntDouble是不是一个可行的解决方案.在某种程度上,这种转换会失去精确度.例如,以下代码不会返回您可能直观的预期.(Swift 3.0)

Double(Int.max - 1) < Double(Int.max) // false!
Run Code Online (Sandbox Code Playgroud)

如果你需要高精度的精度并且不需要担心负指数 - 无论如何通常无法用整数求解 - 那么这种尾递归求幂算法的实现是你最好的选择.根据这个SO答案,这是"在非对称加密中对大量数字进行模幂运算的标准方法".

// using Swift 5.0
func pow<T: BinaryInteger>(_ base: T, _ power: T) -> T {
    func expBySq(_ y: T, _ x: T, _ n: T) -> T {
        precondition(n >= 0)
        if n == 0 {
            return y
        } else if n == 1 {
            return y * x
        } else if n.isMultiple(of: 2) {
            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) 
}
Run Code Online (Sandbox Code Playgroud)


Le *_*inh 10

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

let result = 1 << n
Run Code Online (Sandbox Code Playgroud)


小智 10

Int其他答案都很好,但如果愿意的话,只要指数为正,您也可以通过扩展来实现。

extension Int {   
    func pow(toPower: Int) -> Int {
        guard toPower >= 0 else { return 0 }
        return Array(repeating: self, count: toPower).reduce(1, *)
    }
}

2.pow(toPower: 8) // returns 256
2.pow(toPower: 0) // returns 1
Run Code Online (Sandbox Code Playgroud)


GoZ*_*ner 6

如果您确实需要“仅Int”实现,而又不想强制Double执行,则需要实现它。这是一个简单的实现;有更快的算法,但是可以使用:

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
Run Code Online (Sandbox Code Playgroud)

在实际的实现中,您可能需要进行一些错误检查。

  • 为了缩短它,您可以通过`reduce`调用来实现。return(2 ... power).reduce(base){结果,_ in结果* base}` (2认同)

Hen*_*Two 5

如果您不喜欢运算符重载(尽管^^阅读您的代码的人可能很清楚解决方案),您可以快速实现:

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


Jak*_*231 5

事实证明您也可以使用pow(). 例如,您可以使用以下表达式来表示 10 的 9 次方。

pow(10, 9)
Run Code Online (Sandbox Code Playgroud)

与 一起pow返回powf()afloat而不是 a double。我只在 Swift 4 和 macOS 10.13 上测试过。