mpn_set_str_bits

Niels Möller nisse at lysator.liu.se
Wed Sep 30 07:03:22 UTC 2020


Marco Bodrato <bodrato at mail.dm.unipi.it> writes:

> The loop in mpz_import uses another strategy, a temporary limb.
> This reduces the number of write operations into memory.

And it postpones writing the top limb. Another simplification I tried
failed because it sometimes wrote an extra zero limb.

> static mp_size_t
> mpn_set_str_bits (mp_ptr rp, const unsigned char *sp, size_t sn,
> 		  unsigned bits)
> {
>   mp_size_t rn;
>   mp_limb_t limb;
>   unsigned shift;
>
>   for (limb = 0, rn = 0, shift = 0; sn-- > 0; )
>     {
>       limb |= (mp_limb_t) sp[sn] << shift;
>       shift += bits;
>       if (shift >= GMP_LIMB_BITS)
> 	{
> 	  rp[rn++] = limb;
> 	  shift -= GMP_LIMB_BITS;
> 	  limb = sp[sn];
> 	  if (GMP_LIMB_BITS > CHAR_BIT || shift > 0)
> 	    limb >>= bits - shift;
> 	  else
> 	    limb = 0;

Do we really need to support bits == GMP_LIMB_BITS here? If not, the
above 5 lines could be simplified to just

  limb = sp[sn] >> (bits - shift);

Hmm, at this point, we always have shift < bits, right? So if we write
it as

  limb = (sp[sn] >> 1) >> (bits - 1 - shift);
  
it should be safe in all cases. 

Regards,
/Niels

-- 
Niels Möller. PGP-encrypted email is preferred. Keyid 368C6677.
Internet email is subject to wholesale government surveillance.


More information about the gmp-devel mailing list