2014-06-23 5 views
10

Ich schreibe einen MsgPack Parser in Swift, um die Sprache zu lernen. Es fühlt sich für diese Aufgabe nicht sehr gut an, aber ich habe Fortschritte gemacht. Jetzt habe ich einen Block getroffen, in dem ich es nicht überzeugen kann, 4 Bytes in einen Float umzuwandeln.Wie konvertiert man 4 Bytes in einen Swift Float?

var bytes:Array<UInt8> = [0x9A, 0x99, 0x99, 0x41] //19.20000 

var f:Float = 0 

memccpy(&f, &bytes, 4, 4) 

print(f) 

Auf dem Spielplatz erhalte ich:

fatal error: Can't unwrap Optional.None Playground execution failed: error: Execution was interrupted, reason: EXC_BAD_INSTRUCTION (code=EXC_I386_INVOP, subcode=0x0).

Irgendwelche Ideen, was als nächstes versuchen?

+1

fallen die & auf Bytes. – Grimxn

Antwort

12

Lassen Sie die & auf &bytes fallen. bytes ist ein Array.

var bytes:Array<UInt8> = [0x9A, 0x99, 0x99, 0x41] //19.20000 

    var f:Float = 0.0 

    memccpy(&f, bytes, 4, 4) // as per OP. memcpy(&f, bytes, 4) preferred 

    println ("f=\(f)")// f=19.2000007629395 

aktualisieren Swift 3

memccpy scheint nicht in Swift zu arbeiten 3. Wie Kommentatoren gesagt haben, verwenden memcpy:

import Foundation 
var bytes:Array<UInt8> = [0x9A, 0x99, 0x99, 0x41] //19.20000 

var f:Float = 0.0 

/* Not in Swift 3 
memccpy(&f, bytes, 4, 4) // as per OP. 

print("f=\(f)")// f=19.2 
*/ 

memcpy(&f, bytes, 4)/

print("f=\(f)")// f=19.2 
+5

Besser: 'memcpy (& f, Bytes, 4)'. - 'memccpy (& f, Bytes, 4, 4)' beendet das Kopieren, wenn das Byte '0x04' im Quellpuffer auftritt. –

+0

Sollte 'var' auch' let' sein, um die konstante Anforderung des zweiten Parameters von memccpy() zu erfüllen? Dies hätte dann eine Compiler-Warnung und erzwungene Bytes angezeigt, die als Bytes geschrieben werden, selbst wenn dies nicht unbedingt erforderlich ist. – sketchyTech

+0

Danke für die Hilfe. Ich bekomme immer noch den gleichen Fehler auf dem Spielplatz, in einem Projekt funktioniert es gut. – Brian

2
public func parseInt32(bytes:[UInt8], offset:Int)->Int32{ 

    var pointer = UnsafePointer<UInt8>(bytes) 
    pointer = pointer.advancedBy(offset) 

    let iPointer = UnsafePointer<Int32>(pointer) 
    return iPointer.memory 

} 

public func parseFloat32(bytes:[UInt8], offset:Int)->Float32{ 
    var pointer = UnsafePointer<UInt8>(bytes) 
    pointer = pointer.advancedBy(offset) 

    let fPointer = UnsafePointer<Float32>(pointer) 
    return fPointer.memory 

}