Welcome to the Monastery | |
PerlMonks |
Re^4: porting C code to Perlby syphilis (Archbishop) |
on Nov 07, 2017 at 12:34 UTC ( [id://1202921]=note: print w/replies, xml ) | Need Help?? |
GMP's rudimentary mpf layer I think "rudimentary" is a fair description, and the GMP's mpf layer documentation even states that "new projects should consider using the GMP extension library MPFR (http://mpfr.org/) instead". I personally think the same advice should be given wrt "old projects", too. One limitation of the mpf layer is that the allocated precision is always a multiple of limb size - where limb size will commonly be either 32 or 64 bits. Another limitation is the absence of both Inf and NaN. Also, the rounding rules are rather odd. The mpf_get_d function which converts the mpf_t to a double (which it then returns) rounds towards zero (ie truncates) - and that seems to be the rounding rule generally used throughout. But if one assigns a higher precision mpf_t to a lower precision mpf_t one doesn't always get what one expects. The following demo has two 128-bit mpf_t variables ($large_1 and $large_2) that have been assigned slightly different values. However, using any sane rounding rules, both of those values should round to the same 64-bit value - as both values have the first 65 bits set && there are other set bits further along. To test this, I assign $large_1 to the 64-bit $little_1, and I assign $large_2 to the 64-bit $little_2, expecting that $little_1 == $little_2. But Rmpf_cmp() reports that $little_1 != $little_2. And Rmpf_get_str() also shows that $little_1 != $little_2. Rmpf_out_str() outputs identical base 2 representations for $little_1 and $little_2 but displays 65 set bits ... which seems rather strange for a 64-bit precision mpf_t: These are not Math::GMPf bugs, because the following C script outputs the same results (though the format is not identical). The mpf documentation does state: <quote> Internally, GMP sometimes calculates with higher precision than that of the destination variable in order to limit errors. Final results are always truncated to the destination variable’s precision. </quote> I suspect that this might account for the above anomalies - though I don't see any obvious connection. One avoids these types of anomalies with the MPFR library. Doing the same exercise with MPFR, one finds that $little_1 == $little_2. And that value is 3.40282366920938463463e38 (rounding to nearest), and 3.40282366920938463445e38 (rounding down). Cheers, Rob
In Section
Seekers of Perl Wisdom
|
|