Jeef
Jeef

Reputation: 27275

Cleaner way in swift3 to read binary into a Float

I'm currently doing this:

let floatData: [UInt8] = [0x00, 0x3F, 0xC0, 0x00, 0x00, 0x66, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x66, 0x00, 0x00, 0x3F, 0xC0, 0x00, 0x00, 0x66, 0x00]


floatData.withUnsafeBufferPointer { (bytes: UnsafeBufferPointer<UInt8>) -> Float in
    let byteOffset = 1
    var floatBytes : UInt32 = (UInt32(bytes[byteOffset]) << 24)
    floatBytes |= (UInt32(bytes[byteOffset+1]) << 16)
    floatBytes |= (UInt32(bytes[byteOffset+2]) << 8)
    floatBytes |= UInt32(bytes[byteOffset+3])

    return Float(bitPattern: floatBytes)
}

Which works fine but is a little cumbersome. I've tried casting my bytes to a UnsafeBufferPointer<UInt32> but the compiler doesn't like that.

Is there a cleaner way to extract this bit pattern that I'm missing?

Thanks

Upvotes: 1

Views: 181

Answers (1)

Martin R
Martin R

Reputation: 539745

A possible solution:

let byteOffset = 1
let result = Data(bytes: floatData[byteOffset..<byteOffset+4]).withUnsafeBytes {
    (ptr: UnsafePointer<UInt32>) in
    Float(bitPattern: UInt32(bigEndian: ptr.pointee))
}
print(result) // 1.5

The Data object is created from an array slice, and the closure is called with a pointer to the data. ptr.pointee dereferences the data, and UInt32(bigEndian:) converts it to host byte order.

Upvotes: 3

Related Questions