将二进制 BIT 转换为数组的索引号 - swift



我需要一种方法来确定或映射二进制位,当设置为 Swift 中array的索引号时。

例如,我有一个uInt64设置了 BIT 0b0010 0000 0000 ...,我想将其转换为范围从 039array的索引号。

因此,msb0lsb39

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

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

更新:

在得到很多有用的反馈之后,我遇到了另一个问题,那就是确定 Swift 中的变量是否已更改:

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

它不适用于 UInt64

XOR 运算符可用于识别哪些位发生了变化:

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

ffsll()("查找第一个集合,长长"(函数计算在差值中设置的最低有效位的位置:

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

如果最低有效位中的更改对应于索引 39在阵列中然后计算

let index = 40 - bitpos

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

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

要识别最近打开的位,请将 exclive-OR 应用于先前和当前值以隔离新位:

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

最新更新