You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Swift 4从二维Double数组中写入部分原始比特数据?

减小二维Float数组文件体积的解决方案

针对你想要通过丢弃无关比特来压缩二维Float数组文件体积的需求,我整理了几个实用的方案,既能达到体积压缩的目的,又能尽量保证数据的可用性:

1. 转换为半精度浮点数(Float16)

Float类型默认是32位(4字节),如果你的数据不需要这么高的精度,直接转成16位半精度浮点数是最直接的方式——每个元素的体积直接减半,相当于丢弃了16位无关紧要的低位比特。

代码示例

var arr: [[Float]] = []
arr.append([1.0, 2.0, 3.0])
arr.append([4.0, 5.0, 6.0])

if let outputStream = OutputStream(url: getFileUrl(), append: true) {
    outputStream.open()
    defer { outputStream.close() } // 确保流最终关闭
    
    for subArray in arr {
        for item in subArray {
            // 将32位Float转换为16位半精度浮点数,自动丢弃低位比特
            let halfPrecisionValue = Float16(item)
            // 获取半精度值的原始字节并写入流
            withUnsafeBytes(of: halfPrecisionValue) { byteBuffer in
                _ = outputStream.write(byteBuffer.baseAddress!, maxLength: byteBuffer.count)
            }
        }
    }
}

注意:读取文件时需要反向转换,把16位字节转回Float16再转成Float,保证数据能正确还原。

2. 用定点数替代浮点数

如果你的数据有明确的数值范围和精度要求(比如只需要保留两位小数、数值在0-100之间),可以把浮点数转换为整数存储——这相当于完全丢弃浮点数的小数部分冗余比特,用更紧凑的整数格式存储。

比如假设你的数值范围是0-100,需要保留两位小数:

for subArray in arr {
    for item in subArray {
        // 把浮点数乘以100转成整数,保留两位小数
        let fixedPointValue = UInt16(item * 100)
        // 写入整数的字节(2字节,比Float的4字节小一半)
        withUnsafeBytes(of: fixedPointValue) { byteBuffer in
            _ = outputStream.write(byteBuffer.baseAddress!, maxLength: byteBuffer.count)
        }
    }
}

读取时只需要把整数除以100即可还原浮点数,完全不会丢失你需要的精度。

3. 结合轻量压缩进一步缩小体积

如果上面的方案还不够,你可以在写入字节流的同时加上轻量压缩(比如zlib),利用数据的重复性进一步减小体积。苹果提供了Compression框架可以直接使用:

import Compression

if let outputStream = OutputStream(url: getFileUrl(), append: true) {
    // 用zlib压缩包装原始输出流
    guard let compressedStream = CompressionOutputStream(outputStream: outputStream, algorithm: .zlib) else {
        return
    }
    compressedStream.open()
    defer { compressedStream.close() }
    
    for subArray in arr {
        for item in subArray {
            let halfPrecisionValue = Float16(item)
            withUnsafeBytes(of: halfPrecisionValue) { byteBuffer in
                _ = compressedStream.write(byteBuffer.baseAddress!, maxLength: byteBuffer.count)
            }
        }
    }
}

这种方式会在丢弃比特的基础上,再通过压缩算法进一步降低文件体积,适合数据有较多重复规律的场景。

关键注意事项

  • 无论用哪种方案,先测试精度损失是否在你的可接受范围内,避免因过度压缩导致数据失效。
  • 读取文件时必须和写入的格式严格对应(比如写入Float16就必须读取Float16,写入定点整数就必须读取整数再转换)。

内容的提问来源于stack exchange,提问作者Victor 'Chris' Cabral

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.29 06:53:34