Beefy Boxes and Bandwidth Generously Provided by pair Networks
Do you know where your variables are?
 
PerlMonks  

Re^4: Converting bytes to floats

by syphilis (Archbishop)
on Apr 18, 2023 at 05:40 UTC ( [id://11151725]=note: print w/replies, xml ) Need Help??


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

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

Replies are listed 'Best First'.
Re^5: Converting bytes to floats
by ikegami (Patriarch) on Apr 18, 2023 at 13:31 UTC

    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.

Re^5: Converting bytes to floats
by stevieb (Canon) on Apr 18, 2023 at 08:35 UTC
    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

        Quick question: The string printed is different, but are the values different? (Like, would you get different output for all three if you used printf "%.10000g\n", unpack 'd', pack 'd', sqrt 2?)

        For those that might be interested, this linked code stringifies any double using decimal notation (as opposed to scientific notation). It will return the stored number exactly, or you can specify a precision. I'm not sufficiently familiar with the other two formats you mentioned to know whether it will work with them, but I think it will if you specify a precision. The default precision will definitely needs to be adjusted to support those formats.

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: note [id://11151725]
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others avoiding work at the Monastery: (2)
As of 2024-04-20 01:27 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found