【问题标题】:4 bytes to a Float in a swift gives an unexpectedly small result快速将 4 个字节转换为浮点数会产生出乎意料的小结果
【发布时间】:2015-03-15 08:26:50
【问题描述】:

我正在尝试从 Swift according to this answer 中的二进制流重构浮点数。据我所知,字节是正确的,但结果浮点数不正确。

func didReceive(data: NSData!) {
    var x:Float = 0

    var bytes:[UInt8] = [UInt8](count: 4, repeatedValue: 0)
    data.getBytes(&bytes, range: NSMakeRange(0, 4))
    memcpy(&x, bytes, 4)

    NSLog("x:%f bytes:[%d, %d, %d, %d]", x, bytes[0], bytes[1], bytes[2], bytes[3]);
}

这个函数打印出以下内容:

x:0.000000 bytes:[25, 0, 0, 0]

当我在调试器中检查 x 时,它会将值报告为:

0.0000000000000000000000000000000000000000000350324616

但是,字节[25,0,0,0] 应该是十六进制的0x19000000,我认为是should translate to about 6.617

我的错误在哪里。 Swift 浮点数不是 IEEE754 32 位浮点数吗?

【问题讨论】:

  • 这看起来有点像字节顺序问题,但我没有使用 Swift 的经验,无法真正诊断问题。

标签: swift binary


【解决方案1】:

您在 little-endian 平台上,因此您的数组相当于 32 位整数 0x00000019,作为 IEEE 单精度浮点数,它是 approximately 3.5 * 10-44

【讨论】:

  • 有趣。因此,如果我在其中添加 bytes = bytes.reverse() 行,x 将变为 0.0000000000000000000000066174449,这似乎至少有正确的数字,但仍然相差几个数量级。
  • 不,没有任何数量级的差异。您链接的页面给出的答案约为 6.617 * 10^-24。这就是“E-24”后缀的意思。
  • 哈哈!错过了。谢谢抢
【解决方案2】:

仔细检查page you linked to。它显示 0x19000000 转换为 6.617...E-24

从另一个方向来看,你可以得到 6.617 的十六进制模式,如下所示:

String(unsafeBitCast(6.617 as Float, UInt32.self), radix: 16)

给你0x40D3BE77

顺便说一句,如果您想尝试一种没有memcpy 的方法,这应该可以:

let bytes: [UInt8] = [0x40,0xD3,0xBE,0x77]

let f = bytes.reverse().withUnsafeBufferPointer {
    UnsafePointer<Float>($0.baseAddress).memory
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-02-09
    • 2021-06-04
    • 1970-01-01
    • 2016-08-17
    • 2018-05-26
    • 1970-01-01
    • 2023-03-11
    相关资源
    最近更新 更多