代码之家  ›  专栏  ›  技术社区  ›  user1574598

将二进制位转换为数组-Swift的索引号

  •  0
  • user1574598  · 技术社区  · 8 年前

    当设置为 array 用Swift。

    例如,我有一个 uInt64 这有点过时了 0b0010 0000 0000 ... ,我想用一个 大堆 范围从 0 39

    所以 msb 可能是 0 lsb 可能是 39

    此外,我需要一种方法来识别最近切换的位。

    例如,假设第一个是: 0b0010 0000 0000 .... 第二个是 0x0010 0010 0000 .... 直到整数达到其最高值,即。 0xFFFFFFFF..

    更新 :

    var changedValue: UInt64? {
                            willSet(newValue : UInt64) {
                                guard let oldValue = value, new = newValue else { return }
                                if oldValue != new { oldValue ^ newValue }
                                }
                            }
    

    它不适用于UInt64

    2 回复  |  直到 8 年前
        1
  •  1
  •   Martin R    8 年前

    异或运算符可用于识别哪些位已更改:

    let oldValue: UInt64 = 0b0010_0000_0000
    let newValue: UInt64 = 0b0010_0010_0000
    
    let diff = oldValue ^ newValue
    

    ffsll() (“find first set,long long”)函数计算最低有效位的位置,该位为 设置 区别在于:

    let bitpos = Int(ffsll(Int64(bitPattern: diff)))
    print(bitpos) // 6
    

    如果最低有效位的变化对应于索引39 在数组中,然后计算

    let index = 40 - bitpos
    
        2
  •  1
  •   vacawama    8 年前

    一种基本方法是将数字右移,直到它变为零,并跟踪执行该操作所需的次数:

    func maskToIndex(_ mask: UInt64) -> Int {
        var mask = mask
        var result = 40
    
        repeat {
            mask >>= 1
            result -= 1
        } while mask != 0
    
        return result
    }
    
    print(maskToIndex(0x0000000001))  // 39
    print(maskToIndex(0x0000000002))  // 38
    print(maskToIndex(0x0000000004))  // 37
    
    print(maskToIndex(0x8000000000))  // 0
    print(maskToIndex(0x4000000000))  // 1
    print(maskToIndex(0x2000000000))  // 2
    

    要识别最近打开的位,请对以前和当前值应用异或以隔离新位:

    let previous = 0b100
    let current = 0b110
    let newbit = previous ^ current  // newbit = 2 = 0b010