如何在Swift中使用位操作?
问题描述:
我需要形成一个20字节的数据包,并通过蓝牙将有效载荷发送到硬件外设。如何在Swift中使用位操作?
这20字节的数据包内部分为14个数据集,每个11位,最后6位应该是空字符。
因此,总计: 160位(20个字节)= 14(套)* 11(比特)+ 6(空字符)
的11位被再次分成3组2位,3位和6位。然而,这对主要问题并不重要,我现在可以通过采用'Int16'来形成11位。我会做移位操作来过滤11位,我知道这一点。
如果我只有一个数据集,那么我应该填写所有20个字节,除了前面的11位空字符,如果两个数据集,然后除了22位之外的所有应该是空字符和分别。
我面临的问题是形成这个连续的160位,因为奇数位是11.我想采取一个'诠释'和做移位(< <)操作,然后按位或(|)但Int是64位。
目前我认为采取20个固定大小的字符数组将适合这种情况。尽管在概念上我认为这是最好的方式,但我无法通过所有条件来实现这一目标。我想我需要把所有的逻辑放在一个循环中。
任何人都可以告诉是否实现这一目标的正确方法,并指导我解决它,如果这是最好的方法。如果有的话,或者指出其他任何方式。
答
您不需要将所有数据集打包成20字节的数组,直到最后,因此请将它们保存在长度为14的Int
数组中。使用这种方式更容易。当您需要通过将其发送至硬件,将其转换为UInt8
数组长度20:
struct DataPacket {
var dataSets = [Int](count: 14, repeatedValue: 0)
func toCArray() -> [UInt8] {
var result = [UInt8](count: 20, repeatedValue: 0)
var index = 0
var bitsRemaining = 8
var offset = 0
for value in self.dataSets {
offset = 10
while offset >= 0 {
let mask = 1 << offset
let bit = ((value & mask) >> offset) << (bitsRemaining - 1)
result[index] |= UInt8(bit)
offset -= 1
bitsRemaining -= 1
if bitsRemaining == 0 {
index += 1
bitsRemaining = 8
}
}
}
return result
}
}
// Usage:
var packet = DataPacket()
packet.dataSets[0] = 0b11111111111
packet.dataSets[1] = 0b00000000011
// etc...
let arr = packet.toCArray()
有很多移位操作回事,所以我无法解释这一切。一般的理想是将这11位数据集中的每一个分配到字节中,并根据需要溢出到下一个字节。
答
通过代码的不同提出的解决方案的一种变体:
struct DataPacket {
var dataSets = [Int16](count: 14, repeatedValue: 0)
func getPacket() -> [UInt8] {
var packet = [UInt8](count: 20, repeatedValue: 0)
var idxPacket = 0
for dataSet in dataSets {
for idxBit in 1...11 {
if dataSet & 1 << (11 - idxBit) != 0 {
packet[idxPacket/8] |= UInt8(0b1000_0000 >> (idxPacket % 8))
}
idxPacket += 1
}
}
return packet
}
}
谢谢你的详细代码。我把代码放入游乐场,并尝试了几个样本测试,它运行良好,我也了解完整的代码。再次感谢你。 :) –