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