如何在 Swift 中将 Floats 的 ContiguousArray 转换为字节数组?

Posted

技术标签:

【中文标题】如何在 Swift 中将 Floats 的 ContiguousArray 转换为字节数组?【英文标题】:How to convert an ContiguousArray of Floats into a byte array in Swift? 【发布时间】:2019-11-21 18:25:26 【问题描述】:

我试图在 Swift 中将 Floats 的 ContiguousArray 转换为字节数组,但如果不使用 for 循环就找不到聪明的方法。我一直在关注以前的帖子,例如How to convert a double into a byte array in swift?,但是如果不逐个迭代地获取每个元素,我就无法检索数组的内容。

有没有一种优雅的方法可以直接将 ContiguousArray 的字节直接“复制”到字节数组?

PS:我已经成功实现了将结构转换为字节数组,但不能对数组做同样的事情。

【问题讨论】:

您能否编辑您的帖子并显示所需的输入和输出 【参考方案1】:

您可以使用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)

字节数组包含以主机字节顺序表示的浮点数的二进制表示(在所有当前 Apple 平台上都是小端序)。可以转换为大端,但不能没有到整数数组的中间副本:

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) @LeoDabus:好建议!甚至 withUnsafeBytes(Array.init) 也可以工作(使用自动类型推断)。 反方向会怎样? 非常感谢! Array($0)Array.init 成功了。谢谢你们两位 MartinR @LeoDabus @jiko meta.stackexchange.com/questions/5234/…

以上是关于如何在 Swift 中将 Floats 的 ContiguousArray 转换为字节数组?的主要内容,如果未能解决你的问题,请参考以下文章

在字母数字 NSString 中将 FLOATS 向上/向下舍入为 INTS

如何在 Python 中将浮点数列表输出到二进制文件

如何在 Swift 中将 Int 转换为字符

如何在 Swift 中将 JSON 写入 Realm

如何在 Swift 中将文本居中?

如何在 Swift 中将 UITextField 文本居中