Как преобразовать UInt16 в массив битов - PullRequest
0 голосов
/ 14 января 2019

Я пытаюсь преобразовать UInt16 в массив битов, с чего мне начать?

Мне нужно преобразовать UInt16 в массив, чтобы я мог сдвигать биты. Например, 1110, сдвинутый вправо на 2, равен 1011, или если я делаю

var i: UInt16 = 5
i = i >> 3

он вернет 0, однако я хочу, чтобы он вернул 40960. В двоичном виде это будет выглядеть как

0000000000000101 >> 3 = 1010000000000000 (40960)

Я не знаю, с чего начать с этой проблемой, поэтому любая помощь приветствуется

Ответы [ 2 ]

0 голосов
/ 14 января 2019

Вы можете определить новый оператор сдвига битов, который определяет «циклическое изменение» или, точнее, двоичное вращение, как показано ниже:

infix operator <<&
infix operator >>&

extension BinaryInteger {
    static func <<&<RHS:BinaryInteger>(lhs:Self, rhs:RHS) -> Self {
        // Do normal bit shifting
        let shifted = lhs << rhs
        // If the result is 0, do a rotation by shifting in the opposite direction
        // by the maximum number of bits - original rotation
        // otherwise return the regularly shifted value
        return shifted == 0 ? lhs >> (lhs.bitWidth - Int(rhs)) : shifted
    }

    static func >>&<RHS:BinaryInteger>(lhs:Self, rhs:RHS) -> Self {
        let shifted = lhs >> rhs
        return shifted == 0 ? lhs << (lhs.bitWidth - Int(rhs)) : shifted
    }
}

Затем используйте его как обычные операторы сдвига битов:

UInt16(5) >>& 3 // 40960
UInt8(128) <<& 1 // 1
UInt8(128) << 1 // 0
0 голосов
/ 14 января 2019

Вы можете повернуть биты 16-разрядного целого числа без знака следующим образом:

func rotateLeft(_ n: UInt16, by shift: Int) -> UInt16 {
    let sh = shift % 16

    guard sh != 0 else { return n }

    return n << sh + n >> (sh.signum() * (16 - abs(sh)))
}

let num: UInt16 = 0b0100_0000_0000_0000     //16384
let result1 = rotateLeft(num, by: 2)        //1
let result2 = rotateLeft(num, by: -2)       //4096

let num2: UInt16 = 0b1000_0000_0000_0001    //32769
let result3 = rotateLeft(num2, by: 1)       //3
let result4 = rotateLeft(num2, by: -1)      //49152
...