Beefy Boxes and Bandwidth Generously Provided by pair Networks
Welcome to the Monastery
 
PerlMonks  

Re: Introspection into floats/NV

by ikegami (Patriarch)
on Jun 03, 2025 at 16:03 UTC ( [id://11165222]=note: print w/replies, xml ) Need Help??


in reply to Introspection into floats/NV

I've used this:

sub double_to_bin { my $n = shift; my ( $s, $e, $m ) = unpack "a1 a11 a52", unpack "B64", pack "d>", $n; $e = oct( "0b$e" ); if ( $e == 0x7FF ) { if ( $m =~ /^0+\z/ ) { return $s ? "-inf" : "+inf" ; } else { return "nan"; } } my $n_bin = ( $e ? "1" : "" ) . $m; $e -= 1023; if ( $e < 0 ) { $n_bin = "0." . ( "0" x ( -$e - 1 ) ) . $n_bin; } else { my $z = ( $e + 1 ) - length( $n_bin ); if ( $z >= 0 ) { $n_bin .= "0" x $z; } else { substr( $n_bin, $e+1, 0, "." ); } } $n_bin =~ s/^0+(?=[01])//; if ( $n_bin =~ /\./ ) { #$n_bin =~ s/0+\z//; $n_bin =~ s/\.\z//; } $n_bin = ( $s ? "-" : "" ) . $n_bin; return $n_bin; }

Handles subnormals, infinities and NaNs. [Updated to handle the latter two.]


To print the exact value in decimal, you need up to 1074 decimal places (%.1074f) or 751 in scientific notation (%.751g) for IEEE doubles.

$ perl -e'printf "%.751g\n", unpack "d", pack "Q", 1' 4.94065645841246544176568792868221372365059802614324764425585682500675 +507270208751865299836361635992379796564695445717730926656710355939796 +398774796010781878126300713190311404527845817167848982103688718636056 +998730723050006387409153564984387312473397273169615140031715385398074 +126238565591171026658556686768187039560310624931945271591492455329305 +456544401127480129709999541931989409080416563324524757147869014726780 +159355238611550134803526493472019379026810710749170333222684475333572 +083243193609238289345836806010601150616980975307834227731832924790498 +252473077637592724787465608477820373446969953364701797267771758512566 +055119913150489110145103786273816725095583738973359899366480994116420 +5702637090279242767544565229087538682506419718265533447265625e-324

Replies are listed 'Best First'.
Re^2: Introspection into floats/NV
by syphilis (Archbishop) on Jun 03, 2025 at 22:33 UTC
Re^2: Introspection into floats/NV
by LanX (Saint) on Jun 03, 2025 at 16:17 UTC
    Thanks, the second unpack is a good workaround! :)

    printf "%a" should hopefully handle all edge cases.

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    see Wikisyntax for the Monastery

      I wrote this before %a was introduced. But %a produces scientific notation, whereas the above doesn't.

        > But %a produces scientific notation, whereas the above doesn't.

        my issue with %a is rather that it's called "hex float" but the exponent is decimal ... LOL.

        I'm happy that it exists anyway, since different builds can have other floats configured, plattforms have various endianness too.

        Furthermore it's a valid number format in Perl.

        DB<18> say 0x1p+10 - 1 1023

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        see Wikisyntax for the Monastery

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others rifling through the Monastery: (7)
As of 2025-07-17 10:41 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found

    Notices?
    erzuuliAnonymous Monks are no longer allowed to use Super Search, due to an excessive use of this resource by robots.