develooper Front page | perl.perl5.porters | Postings from May 2018

subnormal f/p hex literals and g++

Thread Next
From:
Dave Mitchell
Date:
May 1, 2018 15:27
Subject:
subnormal f/p hex literals and g++
Message ID:
20180501152726.GK558@iabyn.com
On blead compiled with gcc:

    $ p -le'print "bad" if 0x1.fffffffffffffp-1022 == 0.0'
    $ 

On blead compiled with g++:

    $ p -le'print "bad" if 0x1.fffffffffffffp-1022 == 0.0'
    bad
    $ 

It turns out that perl's handling of subnormal f/p hex literals goes wrong
under 'g++ -ansi'.  scan_num() in toke.c does effectively the following
when toking 0x1.fffffffffffffp-1022 :


    hexfp_frac_bits = 52;         # the number of bits in .fffffffffffff
    hexfp_exp = -1022;
    hexfp_exp -= hexfp_frac_bits; # now -1074

    hexfp_mult = Perl_pow(2.0, hexfp_exp);

On linux at least, the Perl_pow() macro expands to plain pow(),
and under 'gcc' and 'g++' it returns the smallest possible subnormal
value; under 'g++ -ansi' it returns 0.0.

It seems that under -ansi, a different inline wrapper function from
/usr/include/c++/7/cmath is used, which returns 0 rather than a denorm
value.

So, two questions:

is this a reasonable thing for pow() to do;
in that case, should we modify scan_num() to avoid pow() and/or avoid
heading into subnormal territory?

For 5.28, I've marked some tests in t/op/sprintf2.t as TODO if
the literal value gets returned as zero.

-- 
My get-up-and-go just got up and went.

Thread Next


nntp.perl.org: Perl Programming lists via nntp and http.
Comments to Ask Bjørn Hansen at ask@perl.org | Group listing | About