Mam projekt, w którym funkcja otrzymuje cztery znaki 8-bitowe i musi przekonwertować wynikowy 32-bitowy zmiennoprzecinkowy IEEE-754 na zwykły numer Perla. Wygląda na to, że powinien istnieć szybszy sposób niż działający kod poniżej, ale nie byłem w stanie znaleźć prostszej funkcji, która działa.Jak mogę przekonwertować cztery znaki do 32-bitowego float IEEE-754 w Perlu?
To nie działa, ale wydaje się, że jest w pobliżu:
$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));
Ktoś ma lepszy sposób?
Jestem zaintrygowany tym, że Twój urywek "nie działa, ale jest blisko" - czy potrafisz wskazać różnice? Na przykład. biorąc wynik rozpakowania() i przekształcenia go z powrotem na 4 bajty, a następnie szukając bitów, które różnią się między wejściowym a końcowym wyjściem? –