Beefy Boxes and Bandwidth Generously Provided by pair Networks
No such thing as a small change
 
PerlMonks  

Re^6: Defining an XS symbol in the Makefile.PL

by jcb (Parson)
on Aug 18, 2019 at 22:35 UTC ( [id://11104666]=note: print w/replies, xml ) Need Help??


in reply to Re^5: Defining an XS symbol in the Makefile.PL
in thread Defining an XS symbol in the Makefile.PL

The main reason that I included an #error directive is to catch the case where LU_NV_BITS has not been set at all.

Also, I simply copied your probe logic, but I must ask if you are sure that that is the right way to do it. Reading a value from %Config for one test, evaluating an expression for another, and then just using a default seems strange to me. Are you sure $Config{nvsize} will not give you 10 and 16 for the 80 and 128 bit cases?

Replies are listed 'Best First'.
Re^7: Defining an XS symbol in the Makefile.PL
by syphilis (Archbishop) on Aug 19, 2019 at 01:40 UTC
    Also, I simply copied your probe logic, but I must ask if you are sure that that is the right way to do it.

    Thanks for querying - I've just now realized that I've forgotten about the DoubleDouble type of long double. (Given the amount of time I've spent puzzling over that beast, I'm actually quite appalled that I could do that !!)
    It's a case that technically should be given special handling. At the moment, the DoubleDoubles will end up in the elsif{} block, demanding a precision of "%.36" which is sufficient for the vast majority of cases ... but not all :-(
    The DoubleDouble is an nvtype that is rarely encountered and I'm tempted to leave the code as it is and just change the comment from:
    # IEEE long double or __float128 to # IEEE long double or __float128 or DoubleDouble
    I'll have to do some testing on my DoubleDouble builds and look at the options.

    On recent perls the approach that I took could be replaced by examining $Config{nvtype} in conjunction with $Config{longdblkind} (when nvtype is long double).
    However, for perls prior to 5.22, $Config{longdblkind} is unavailable, so we need to use another method.
    Besides, using nvtype and longdblkind looks even messier than what I've done - though the logic is perhaps more transparent.

    The 'long double' is the type that makes things awkward - it can be either 64, 80, or 128 bits, and on 64-bit builds of perl the 80-bit, 128-bit and DoubleDouble long doubles all typically report a $Config{nvsize} value of 16, thus severely limiting the usefulness of that Config value.

    Cheers,
    Rob

      Of course a 64-bit Perl will report both 80-bit and 128-bit floats as 16 bytes: the alignment rules require that much storage since both types span two 64-bit words. Do the different long double types have differing ranges? Could you test progressively larger numbers and arrive at an answer that way?

      Perhaps something like: (obviously untested and the numbers are bogus)

      my @bigfloats = ([6, '1.234e56', '1e50'], [12, '2.3456e789', '1e777'], + # "lorem ipsum ..." [18, '3.45678e9012', '1e8994'], [36, '4.567890e12345' +, '1e12329']); # Each of the above arrays has (0) the number of decimal digits of pre +cision needed, # (1) a number near the large end of the +range for a type, # (2) a number near epsilon for the sampl +e number (1) my $prec = 0; foreach my $step (@bigfloats) { $prec = $step->[0]; my $num = (0+$step->[1]); my $sum = ($num + $step->[2]); last unless $num eq $step->[1] and $sum > $num; } $defines .= ' -DLU_NV_PREC='.$prec;

      Then in XS: (here is the macro trick I mentioned earlier in "(cpp)Stringification")

      ... #define STR_(s) #s #define DSTR_(s) STR_(s) ... #ifndef LU_NV_PREC #error "LU_NV_PREC is not set" #endif #define MY_FORMAT "%." DSTR_(LU_NV_PREC) "e" ...
        Do the different long double types have differing ranges?

        Yes, but we don't need to know anything about the range for the task at hand.
        We just need to know the maximum number of bits of precision for each type, and the number of decimal digits required to accurately handle each of those maximum precisions.
        That is:
        53 bits needs 17 decimal digits
        64 bits needs 21 decimal digits
        113 bits needs 36 decimal digits

        The DoubleDouble can actually accommodate some (not all) 2098-bit values - which would require 633 decimal digits, but I'm still pondering what should be done about that.
        I doubt that"%.632" NVgf will produce reliable results anyway.
        Unpacking the bytes of the NV is probably cheaper and quicker than obtaining a numeric value, so maybe that's a better path to take for *all* NVs - not just the DoubleDouble.

        Cheers,
        Rob

Log In?
Username:
Password:

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

How do I use this?Last hourOther CB clients
Other Users?
Others musing on the Monastery: (4)
As of 2024-04-23 23:45 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found