Beefy Boxes and Bandwidth Generously Provided by pair Networks
Perl Monk, Perl Meditation
 
PerlMonks  

Re^6: Converting bytes to floats

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


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

.... 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

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

    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.

      would you get different output for all three if you used printf "%.10000g\n", unpack 'd', pack 'd', sqrt 2 ?

      As is desirable, it's the same (and correct) output in all three cases:
      D:\>perl -le "printf '%.10000g', unpack 'd', pack 'd', sqrt 2;" 1.4142135623730951454746218587388284504413604736328125
      which, incidentally, is exactly the value of the double precision representation of sqrt 2.

      Cheers,
      Rob

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others taking refuge in the Monastery: (7)
As of 2024-03-29 13:17 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found