in reply to Re^2: Converting bytes to floats
in thread Converting bytes to floats

ok? Did you try what I provided? I still believe you're asking for

say for unpack "d*", $contents; # To print them as you were.
my @numbers = unpack "d*", $contents; # To store them in an array.

unpack

Mini-Tutorial: Formats for Packing and Unpacking Numbers

Replies are listed 'Best First'.
Re^4: Converting bytes to floats
by syphilis (Archbishop) on Apr 18, 2023 at 05:40 UTC
    Did you try what I provided?

    I think it's theoretically possible that the OP did follow the advice but struck an endianness issue which, to be resolved, would presumably require either:
    unpack "d<*", $contents or unpack "d>*", $contents
    Cheers,
    Rob

      If they're dealing with non-native architectures, they might have bigger problems than endianness. Unpack will only be useful if the both platforms use the same format for floats.

      I assumed they are on an x86 or x86-64, as I would have expected them to mention it if it wasn't the case.

      I also assumed that they were referring to IEEE double-precision floats. Though I did give them the information they needed for IEEE single-precision floats too via the link.

      struck an endianness issue

      Man, this takes me back several years to when I started coding low-level stuff for my microcontroller sensor projects.

      Collecting data and flipping bits...fine, but swapping entire bytes!?! :)

        .... but swapping entire bytes ...

        In addition to the endianness issue, there's also the "precision" issue that can trip one up when print()ing NV values.
        On a perl whose nvtype is double:
        D:\>perl -le "print unpack 'd', pack 'd', sqrt 2;" 1.4142135623731
        On a perl whose nvtype is the 80-bit extended precision long double:
        D:\>perl -le "print unpack 'd', pack 'd', sqrt 2;" 1.41421356237309515
        On a perl whose nvtype is either the IEEE 754 long double or the __float128:
        D:\>perl -le "print unpack 'd', pack 'd', sqrt 2;" 1.41421356237309514547462185873883
        You might think that the differences in those 3 one liners occur because pack 'd', sqrt 2 has returned different bytes in each of those 3 one liners, but that's not so.
        In each of those 3 one-liners pack 'd', sqrt 2 returned exactly the same byte.
        So, it must be that the unpacking returned different values ? Wrong again.
        It's the way that perl's print() function conceals the actual value returned by unpack 'd', pack 'd', sqrt 2 that accounts for the anomalies.

        Perl is bullshitting in all 3 cases (and knows it).
        On a perl whose nvtype is double:
        D:\>perl -le "print 'WTF' if (unpack 'd', pack 'd', sqrt 2) != 1.41421 +35623731;" WTF
        On a perl whose nvtype is the 80-bit extended precision long double:
        D:\>perl -le "print 'WTF' if (unpack 'd', pack 'd', sqrt 2) != 1.41421 +356237309515;" WTF
        On a perl whose nvtype is either the IEEE 754 long double or the __float128:
        D:\>perl -le "print 'WTF' if (unpack 'd', pack 'd', sqrt 2) != 1.41421 +356237309514547462185873883;" WTF
        3 different renditions of the same value - none of them accurate.
        I recall a quote (probably from Larry) from a while ago, along the lines of "perl makes the hard things easy".
        When it comes to certain aspects of the way perl deals with NVs, it's more a case of "perl makes the easy things hard".
        I think it's ridiculous and, although I'm scathing of it, I'm also used to it and sort of like the way that it keeps me on my toes ;-)

        So ... for a given $byte, what one expects to be returned by unpack "d", $byte can depend not only upon machine endianness, but also on NV type.

        Cheers,
        Rob