我在Swift中创建了一个^^运算符.如何使其像所有其他运算符一样使用Integers和Doubles?
infix operator ^^ { }
func ^^ (number:Int, power: Int) -> Int {
var result = power > 0 ? number : 0
if power > 1 { for x in 1..<power { result *= number } }
return result
}
Run Code Online (Sandbox Code Playgroud)
Mar*_*n R 11
这是一个更加类型安全的实现,使用运算符重载.对于整数类型,您可以定义^^为
infix operator ^^ { associativity left precedence 170 }
func ^^<T : IntegerType, U : IntegerType> (base: T, var power: U) -> T {
if power < 0 { return 0 }
var result : T = 1
var square : T = base
if power > 0 {
if power % 2 == 1 { result *= square }
power /= 2
}
while power > 0 {
square *= square
if power % 2 == 1 { result *= square }
power /= 2
}
return result
}
Run Code Online (Sandbox Code Playgroud)
(我选择了一种更有效的变体,称为"通过重复的平方和乘法取幂".)
对于浮点类型,定义一个协议,涵盖可以转换为的所有类型Double:
protocol DoubleConvertible {
init(_ value: Double)
var doubleValue : Double { get }
}
Run Code Online (Sandbox Code Playgroud)
并作出Float,Double并CGFloat符合该协议:
extension Double : DoubleConvertible {
var doubleValue : Double { return self }
}
extension Float : DoubleConvertible {
var doubleValue : Double { return Double(self) }
}
extension CGFloat : DoubleConvertible {
var doubleValue : Double { return Double(self) }
}
Run Code Online (Sandbox Code Playgroud)
现在浮点指数可以简单地定义为
func ^^<T : DoubleConvertible, U:DoubleConvertible> (base: T, power: U) -> T {
return T(pow(base.doubleValue, power.doubleValue))
}
Run Code Online (Sandbox Code Playgroud)
例子:
let x1 = 2^^3 // Int
let x2 = UInt64(2)^^3 // UInt64
let x3 = 2.0 ^^ 3 // Double
let x4 = Float(2.0) ^^ 3 // Float
let x5 = "a" ^^ "b" // Compiler error
Run Code Online (Sandbox Code Playgroud)
Swift 4的更新:
IntegerType已成为BinaryInteger(SE-0104面向协议的整数)和声明运算符的语法已更改(SE-0077改进的运算符声明.)
以下是带Int指数的所有整数和浮点数的实现:
precedencegroup ExponentiationPrecedence { associativity: right higherThan: MultiplicationPrecedence }
infix operator ^^: ExponentiationPrecedence
func ^^<T : BinaryInteger>(base: T, power: Int) -> T {
if power < 0 { return 0 }
var power = power
var result: T = 1
var square = base
if power > 0 {
if power % 2 == 1 { result *= square }
power /= 2
}
while power > 0 {
square *= square
if power % 2 == 1 { result *= square }
power /= 2
}
return result
}
func ^^(base: Float, power: Int) -> Float {
return pow(base, Float(power))
}
func ^^(base: Double, power: Int) -> Double {
return pow(base, Double(power))
}
func ^^(base: CGFloat, power: Int) -> CGFloat {
return pow(base, CGFloat(power))
}
Run Code Online (Sandbox Code Playgroud)
例子:
let x1 = 2^^3 // Int
let x2 = UInt64(2)^^3 // UInt64
let x3 = 2.0 ^^ -3 // Double
let x4 = Float(2.0) ^^ 3 // Float
// let x6 = "a" ^^ 5 // Compiler error
Run Code Online (Sandbox Code Playgroud)
有关 Swift 4中引入的新协议层次结构,请参阅SE-0104面向协议的整数.
| 归档时间: |
|
| 查看次数: |
1167 次 |
| 最近记录: |