mini-gmp mpz_{get,set}_d not fully compatible with GMP

Marco Bodrato bodrato at mail.dm.unipi.it
Sun Mar 11 04:00:09 UTC 2018


Ciao,

Il Dom, 11 Marzo 2018 12:15 am, Niels Möller ha scritto:
> "Marco Bodrato" <bodrato at mail.dm.unipi.it> writes:

>> double
>> mpz_get_d (const mpz_t u)
>> {
>>   static unsigned int c = 0;
>>   int m;

> I'd prefer more descriptive names for c and m.

In my working version they was named celo and mnk :-)

>>   if (c == 0)
>>     c = gmp_tests_dbl_mant_bits ();
>
> This is *almost* thread-safe. If two threads race in calling this
> function for the first time, it should still work provided that access
> to c is atomic (it doesn't matter if gmp_tests_dbl_mant_bits is called
> twice, producing the same result). That's probably the case on most
> platforms, but not entirely kosher. It would break if the first thread
> writes c, and the second threads reads a non-zero value of c with a mix
> of the old value (zero) and the new value.

... if the compiler inlines the static gmp_tests_dbl_mant_bits function,
and optimizes away the local variable n, directly updating c in the loop,
then it can be a problem... suggestions?
We can declare c as int and n as unsigned. But I fear this is not a real 
obstacle for an optimizer.

> If we could use float.h constants, we wouldn't need to worry.

In GMP we can #if HAVE_FLOAT_H ... but in mini-gmp?

>>   for (x = l; --un >= 0;)
>>     {
>>       x = B*x;
>>       if (m > 0) {
>> 	l = u->_mp_d[un];
>> 	m -= GMP_LIMB_BITS;
>> 	if (m < 0)
>> 	  l &= GMP_LIMB_MAX << -m;
>> 	x += l;
>>       }
>>     }

> Maybe rearrange loop so that

>    if (m < 0)
>      l &= GMP_LIMB_MAX << -m;
>    x += l;

> is done after the loop, and not repeated prior to the loop?

... then we need a second loop to continue with x *= B; ...

Ĝis,
m

-- 
http://bodrato.it/



More information about the gmp-devel mailing list