我需要一种方法来确定或映射二进制位,当设置为 Swift 中array
的索引号时。
例如,我有一个uInt64
设置了 BIT 0b0010 0000 0000 ...
,我想将其转换为范围从 0
到 39
的array
的索引号。
因此,msb
将0
,lsb
将39
此外,我需要一种方法来识别已切换的最新位。
例如,假设第一个是: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