Beefy Boxes and Bandwidth Generously Provided by pair Networks
Keep It Simple, Stupid
 
PerlMonks  

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

by jcb (Hermit)
on Aug 19, 2019 at 02:40 UTC ( #11104676=note: print w/replies, xml ) Need Help??


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

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

Replies are listed 'Best First'.
Re^9: Defining an XS symbol in the Makefile.PL
by syphilis (Bishop) on Aug 19, 2019 at 14:04 UTC
    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

      You seem to misunderstand. The test code I offered above takes advantage of varying ranges to distinguish between known types. The code tests range by doing a string->FP->string round-trip and comparing the result to the original string. It also directly tests available precision by adding a (smaller) value and testing if the sum is larger than the initial value. The highest of these tests that passes defines the number of digits of precision to use.

      It also looks like you may have found a better way to do this that does not require determining the FP type in advance?

        It also looks like you may have found a better way to do this that does not require determining the FP type in advance?

        Reading the bytes works well for comparing NV values, but unfortunately List::Util::uniqnum() also needs to be able to recognize that (eg) the IV "42" and the NV "42.0" are the same value.
        Unfortunately that breaks down when one starts reading the bytes of the NV ;-)

        You can't quite avoid determining the FP type, anyway. For a 16-byte extended precision long double I don't think it's wise to assume that 2 identical NVs would necessarily have the same 6 unused bytes.
        For that type I decided I should locate the unused bytes and not read them. That additionally required that endianness be established (which is quite easy, courtesy of $Config{byteorder}).

        So I'll just go with the original solution. As regards what to do regarding the DoubleDouble, I'm trying to establish whether the deplorable state of stringification that I'm seeing is typical ... or whether it's just *my* system that's suffering.
        If mine is typical, then I'll just do "%.36" NVgf for the DoubleDouble. But if recent improvements have been made then I might try something smarter.
        No-one (apart from me) uses DoubleDouble builds of perl anyway, and I haven't been able to find a failure using "%.36" NVgf so I'm not all that committed to spending too much time on it.

        Cheers,
        Rob

Log In?
Username:
Password:

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

How do I use this? | Other CB clients
Other Users?
Others studying the Monastery: (5)
As of 2019-09-18 05:58 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?
    The room is dark, and your next move is ...












    Results (222 votes). Check out past polls.

    Notices?