2014-11-17 16 views
5

Sto cercando un modo robusto ed elegante per estrarre quattro byte big-endian da un array come Float.Swift: estrae il float dai dati di byte

posso ottenere un UInt32 con i bit tramite qualcosa di simile:

let data: [Byte] = [0x00, 0x00, 0x00, 0x40, 0x86, 0x66, 0x66, 0x00] 
let dataPtr = UnsafePointer<Byte>(data) 
let byteOffset = 3 
let bits = UnsafePointer<UInt32>(dataPtr + byteOffset)[0].bigEndian 

ma non riesco a capire un buon modo per convertire questo in un galleggiante a Swift.

Ad esempio, in Java:

float f = Float.intBitsToFloat(bits) 

o in C:

float f = *(float *)&bits; 

Ho provato colata del DataPtr ad un galleggiante UnsafePointer, ma poi l'endianness è un problema.

Qualche suggerimento?

risposta

5

I tipi a virgola mobile hanno un valore statico _fromBitPattern che restituirà un valore. <Type>._BitsType è un tipo alias per il numero intero senza segno dimensionata correttamente:

let data: [Byte] = [0x00, 0x00, 0x00, 0x40, 0x86, 0x66, 0x66, 0x00] 
let dataPtr = UnsafePointer<Byte>(data) 
let byteOffset = 3 
let bits = UnsafePointer<Float._BitsType>(dataPtr + byteOffset)[0].bigEndian 
let f = Float._fromBitPattern(bits) 

Non si vede che il metodo di completamento automatico, ma è un part of the FloatingPointType protocol. C'è un metodo di istanza che ti restituirà i bit, chiamato ._toBitPattern().

+0

Questo è meglio ... –

+0

Sì, ancora più chiaro. Grazie! – NickHowes

4

Il codice Swift equivalente è

let flt = unsafeBitCast(bits, Float.self) 

che dà 4.2 con i tuoi dati.

0

Ecco la soluzione per Swift 3:

Float(bitPattern: bits)