【问题标题】:Convert byte array to double in Swift在 Swift 中将字节数组转换为双精度
【发布时间】:2015-10-24 17:43:00
【问题描述】:

如何在 Swift 中将字节数组转换为双精度值?

(这是一个 NSInputStream 扩展)

我的 sn-p 附在下面,但它没有返回正确的双精度值:

func readDouble() -> Double
{
var readBuffer = Array<UInt8>(count:sizeof(Double), repeatedValue: 0)

        let numberOfBytesRead = self.read(&readBuffer, maxLength: readBuffer.count)
        let help1 = Int(readBuffer[0] & 0xff) << 56 | Int(readBuffer[1] & 0xff) << 48
        let help2 = Int(readBuffer[2] & 0xff) << 40 | Int(readBuffer[3] & 0xff) << 32
        let help3 = Int(readBuffer[4] & 0xff) << 24 | Int(readBuffer[5] & 0xff) << 16
        let help4 = (Int(readBuffer[6] & 0xff) << 8) | Int(readBuffer[7] & 0xff)
        return Double(help1 | help2 | help3 | help4)
}

【问题讨论】:

  • 数据在输入流中是如何表示的?作为整数或 IEEE 二进制双精度数?哪个字节顺序?你得到什么结果,你期望什么?
  • 这是一个用java编写的双精度数组。
  • 你在问 Swift 的人,所以添加信息可能会有所帮助如何 Java 编写一个双精度数组。
  • println(readBuffer) 显示什么(读取操作后),结果应该是什么?

标签: swift casting type-conversion


【解决方案1】:

很简单:

extension FloatingPoint {

    init?(_ bytes: [UInt8]) {

        guard bytes.count == MemoryLayout<Self>.size else { return nil }

        self = bytes.withUnsafeBytes {

            return $0.load(fromByteOffset: 0, as: Self.self)
        }
    }
}

let array: [UInt8] =  [0, 0, 0, 0, 0, 0, 240, 63]
let num = Double(array) // 1.0

此代码适用于 Swift 中的任何浮点类型。

ma​​cOS 上的 Swift 3.0little-endian 表示 Double

您可以查看我的备忘单以进行字节转换here。 (小/大端数字转换)

【讨论】:

  • 我不明白那个字节数组是如何转换成双精度的。目前在转换数据时遇到问题
  • 什么是你不明白的?这只是一个方便的初始化程序,它将UInt8 数组重新解释为您选择的浮点类型。提供 Swift 期望的正确字节流是你的责任。
【解决方案2】:

我的理解是你的字节数组是二进制表示的序列化。但是,您正在使用的Double 构造函数采用整数值并返回相应的DoubleDouble(3) 返回3.0

正确的构造函数可能是Double(_bits:),但它接受Builtin.FPIEEE64,看起来它的可用性是一个实现细节。您可能应该考虑制作一个 C 函数并将其桥接到 Swift。

【讨论】:

  • 您可以从输入流中直接读取到 Swift Double 变量中,例如 stackoverflow.com/a/25846086/1187415。但这取决于数据表示(这就是我仍在试图弄清楚的)。
猜你喜欢
  • 1970-01-01
  • 2013-03-10
  • 1970-01-01
  • 2012-03-07
  • 2014-11-02
  • 2010-11-21
  • 1970-01-01
  • 1970-01-01
  • 2018-10-02
相关资源
最近更新 更多