Anonymous Monk has asked for the wisdom of the Perl Monks concerning the following question:

I'm trying to decode an byte array, which contains both signed and unsigned encoded floats. I've written this code which prints integers. Your help is appreciated.
my $length = length($contents) / 8; foreach (my $i = 0; $i < $length; $i ++) { my $offset = $i * 8; print ord substr($contents, $offset, 8), "\n"; }

Replies are listed 'Best First'.
Re: Converting bytes to floats
by ikegami (Patriarch) on Apr 17, 2023 at 18:23 UTC
      It's a series of bytes. This powershell works:
      $len = $bytes.Count/8 for( $i = 0 ; $i -lt $len ; $i++) { [System.BitConverter]::ToDouble($bytes, $i * 8 ) }
        Yes, I think, what you are looking for is $number = unpack('d', $bytes);

        If $bytes hold 8 bytes, then unpack will convert that to a number.

Re: Converting bytes to floats
by etj (Priest) on Apr 18, 2023 at 19:04 UTC
    A slightly deranged piece of PDL code I wrote to rapidly decode lots of floats at scale from binary STL files, at https://github.com/PDLPorters/pdl/blob/5b6057ffed3ffc1fe2f8018b28299ecf30e36f35/IO/STL/STL.pm#L152-L170:
    sub _read_binary { my ($fh) = @_; barf "bigfloat" unless(length(pack("f", 1)) == 4); # TODO try to read part name from header (up to \0) seek($fh, 80, 0); my $buf; read($fh, $buf, 4) or warn "EOF?"; my $triangles = unpack(' +L<', $buf); my $bytes = 50 * $triangles; # norm+3vertices * 3float + short with +length of extra my $bytespdl = zeroes PDL::byte(), 50, $triangles; my $bytesread = read($fh, ${$bytespdl->get_dataref}, $bytes); barf "Tried to read $bytes but only got $bytesread" if $bytesread != + $bytes; $bytespdl->upd_data; my $floatpdl = zeroes PDL::float(), 3, 4, $triangles; ${$floatpdl->get_dataref} = ${$bytespdl->slice('0:47')->get_dataref} +; $floatpdl->upd_data; $floatpdl->type->bswap->($floatpdl) if isbigendian(); # TODO check that the unit normal is within a thousandth of a radian # (0.001 rad is ~0.06deg) _as_ndarray($floatpdl->slice(':,1:3')); }
Re: Converting bytes to floats
by Anonymous Monk on Apr 18, 2023 at 14:16 UTC
    Thanks for the help. I was able to get it working by original reply.
    my @doubles = unpack "d*", $contents;
    Some background. This data was produced by a java app and represents points on a chromatogram.