Ich habe ein Array von (unsigned-byte 32)
, die ziemlich viele Daten enthält, einige davon im Gleitkommaformat. Das heißt, einige der Bytes werden als Ganzzahlen behandelt, die Bitfelder enthalten, während einige von ihnen als 32-Bit-Gleitkommazahlen verwendet werden.sbcl: konvertieren (unsigned-byte 32) in single-float
Ich muss die Daten im Array lesen und schreiben.
Leider nimmt die Funktion sb-kernel:make-single-float
ein Argument von (signed-byte 32)
, und sb-kernel:single-float-bits
gibt ein signiertes Wort zurück, so dass sie nicht direkt mit meinem Vektor kompatibel sind. Auf der anderen Seite würde die Umwandlung des Vektors, um vorzeichenbehaftete Bytes zu enthalten, die Bitfeldoperationen schmerzhaft machen.
Diese Bis jetzt habe ich
geschrieben(defun u32-to-sf (x)
(declare (optimize (speed 3) (compilation-speed 0) (debug 0))
(type (unsigned-byte 32) x))
(if (>= x #x80000000)
(sb-kernel:make-single-float (- x #x100000000))
(sb-kernel:make-single-float x)))
, die die richtige Sache tut, aber die generierte Assembly mit bedingtem Sprung und unnötigen Vergleichen und Subtraktionen hässlich aussieht.
Irgendwelche Ideen, wie man sbcl dazu bringt, einfach den bitweisen Inhalt des unsigned-byte
als den bitweisen Inhalt für den Float-to-be zu akzeptieren?
Tatsächlich produziert das den richtigen Assemblercode. Das ganze 'if' ist in diesem Fall natürlich unnötig. Aber auch dies ist ein bisschen hackische Lösung und obwohl es mit der aktuellen Version funktioniert, glaube ich nicht, dass es allgemein sicher ist anzunehmen, dass es auch in der Zukunft funktionieren wird. Gut genug für die Zeit, aber - danke! – jlahd