Ich habe ein Projekt, bei dem eine Funktion vier 8-Bit-Zeichen empfängt und die resultierende 32-Bit-IEEE-754-Gleitkommazahl in eine normale Perl-Zahl konvertieren muss. Es scheint, dass es einen schnelleren Weg geben sollte als der unten stehende Arbeitscode, aber ich konnte keine einfachere Pack-Funktion finden, die funktioniert.Wie kann ich in Perl vier Zeichen in einen 32-Bit IEEE-754 Float konvertieren?
Es funktioniert nicht, aber es scheint, wie es in der Nähe ist:
$float = unpack("f", pack("C4", @array[0..3]); # Fails for small numbers
Works:
@bits0 = split('', unpack("B8", pack("C", shift)));
@bits1 = split('', unpack("B8", pack("C", shift)));
@bits2 = split('', unpack("B8", pack("C", shift)));
@bits3 = split('', unpack("B8", pack("C", shift)));
push @bits, @bits3, @bits2, @bits1, @bits0;
$mantbit = shift(@bits);
$mantsign = $mantbit ? -1 : 1;
$exp = ord(pack("B8", join("",@bits[0..7])));
splice(@bits, 0, 8);
# Convert fractional float to decimal
for (my $i = 0; $i < 23; $i++) {
$f = $bits[$i] * 2 ** (-1 * ($i + 1));
$mant += $f;
}
$float = $mantsign * (1 + $mant) * (2 ** ($exp - 127));
Wer einen besseren Weg?
Ich bin fasziniert, dass Ihr Top-Snippet "nicht funktioniert, aber in der Nähe ist" - können Sie die Unterschiede feststellen? Z.B. indem man das Ergebnis von unpack() nimmt und es zurück in die 4 Bytes umwandelt, und dann nach Bits sucht, die zwischen Eingabe und endgültiger Ausgabe verschieden sind? –