如何在 Swift 中执行循环移位?

Tod*_*odd 1 binary swift

我正在尝试在 Swift 中执行循环移位,目前有以下代码,该代码使用包含我尝试执行循环移位的数字位的字符串。这是我到目前为止的代码,

func circularRightShift(_ input: UInt8, _ amount: UInt8) -> UInt8 {
    guard amount > 0 else { return input }
    var a = String(UInt("\(input)")!, radix: 2)
    if a.count != 8 {
        a = "".padding(toLength: 8-a.count, withPad: "0", startingAt: 0) + a
    }
    for _ in 1...amount {
        a.insert(a.last!, at: a.startIndex)
        a.removeLast()
    }
    return UInt8(a, radix: 2)!
}
Run Code Online (Sandbox Code Playgroud)

这段代码可以正常工作,但是有点慢。有没有更好的方法来实现这一点,可能不使用字符串?提前致谢。

Sch*_*tky 5

另一个更普遍的答案是:

func circularShift<ShiftType: BinaryInteger>(_ first: ShiftType, by shiftAmount: Int) -> ShiftType {
    (first << shiftAmount) | (first >> (first.bitWidth - shiftAmount))
}
Run Code Online (Sandbox Code Playgroud)

您还可以创建一个扩展:

extension BinaryInteger {
    func circularShifted(by shiftAmount: Int) -> Self {
        (self << shiftAmount) | (self >> (self.bitWidth - shiftAmount))
    }
}
Run Code Online (Sandbox Code Playgroud)

为了更加灵活,您可以考虑操作的符号并区分左移和右移:

extension BinaryInteger where Self: UnsignedInteger {
    func rotateLeft(by shiftAmount: Int) -> Self {
        if shiftAmount < 0 {
            return rotateRight(by: -shiftAmount)
        }
        return (self << shiftAmount) | (self >> (self.bitWidth - shiftAmount))
    }
    
    func rotateRight(by shiftAmount: Int) -> Self {
        if shiftAmount < 0 {
            return rotateLeft(by: -shiftAmount)
        }
        return (self >> shiftAmount) | (self << (self.bitWidth - shiftAmount))
    }
}
Run Code Online (Sandbox Code Playgroud)

然后可以像这样使用

let x: UInt8 = 0xE
String(x.rotateLeft(by: 2), radix: 16) // 3A
String(x.rotateRight(by: 2), radix: 16) // A3
Run Code Online (Sandbox Code Playgroud)