如何在Swift中将一个ContiguousArray的浮点数转换为字节数组?

3

我正在尝试将Swift中的ContiguousArray of Floats转换为字节数组,但是没有找到不使用循环的聪明方法。我一直在关注之前的帖子,例如如何将double转换为字节数组在Swift中?,但是我无法检索数组的内容而不是逐个获取每个元素。

是否有一种优雅的方式可以直接将ContiguousArray的字节直接复制到字节数组中?

PS:我已成功实现将结构转换为字节数组,但无法对数组执行相同的操作。


1
请问您能否编辑您的帖子并展示所需的输入和输出? - Leo Dabus
1个回答

5
您可以使用 withUnsafeBytes() 方法,以获取指向数组连续存储的底层字节的缓冲指针,并直接从该缓冲指针初始化一个 [UInt8] 数组。例如:
let floatArray: [Float] = [1.0, 2.0]
// Works also with a ContiguousArray:
// let floatArray: ContiguousArray<Float> = [1.0, 2.0]

let byteArray = floatArray.withUnsafeBytes { Array($0) }
print(byteArray) // [0, 0, 128, 63, 0, 0, 0, 64]

相应地(根据Leo的建议):

let byteArray = floatArray.withUnsafeBytes(Array.init)

该字节数组包含主机字节顺序中浮点数的二进制表示(在所有当前的苹果平台上都是小端)。转换为大端字节顺序是可能的,但需要先将其复制到整数数组中:

let floatArray: ContiguousArray<Float> = [1.0, 2.0]
let intArray = floatArray.map { $0.bitPattern.bigEndian }
let byteArray = intArray.withUnsafeBytes(Array.init)
print(byteArray) // 63, 128, 0, 0, 64, 0, 0, 0]

反向转换:一个简单的方法是

let floatArray2 = byteArray.withUnsafeBytes { Array($0.bindMemory(to: Float.self)) }
print(floatArray2) // [1.0, 2.0]

然而,这需要字节数组的元素存储对于浮点数进行适当的 对齐。如果不能保证对齐,则可以执行以下操作:
var floatArray2 = [Float](repeating: 0.0, count: byteArray.count / MemoryLayout<Float>.stride)
_ = floatArray2.withUnsafeMutableBytes { byteArray.copyBytes(to: $0) }
print(floatArray2) // [1.0, 2.0]

withUnsafeBytes([UInt8].init) - Leo Dabus
1
@LeoDabus:好建议!即使使用withUnsafeBytes(Array.init)也可以工作(具有自动类型推断)。 - Martin R
反方向应该怎么做? - Leo Dabus
非常感谢!Array($0)Array.init解决了问题。感谢MartinR和LeoDabus两位。 - jiko
@jiko https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work@jiko https://meta.stackexchange.com/questions/5234/how-does-accepting-an-answer-work - Leo Dabus

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接