mini-gmp: mpz_init_set_str fails on leading zeroes

Austyn Krutsinger akrutsinger at gmail.com
Thu Jul 21 19:32:16 UTC 2016


On Thu, Jul 21, 2016 at 5:46 PM, Axel Miller <axel.miller at ppi.de> wrote:

> Wouldn't that break mpz_sgn(v)
> if i use mpz_set_str(v, "00000000000000000000000000000000000000000000",
> 10) ?
>

​
I'm not too sure about what will happen with mpz_sgn. mpz_sizeinbase has a
problem handling all
​zeros as you have above. I presume
mpn_get_str_bits
​ would also fail because it too calls
mpn_limb_size_in_base_2
​(up[0]) in this specific case.​
​

3980  size_t
3981   mpz_sizeinbase (const mpz_t u, int base)
3982   {
           /*snip*/
3996
3997     up = u->_mp_d;
3998
3999     bits = (un - 1) * GMP_LIMB_BITS + mpn_limb_size_in_base_2 (up[un-1]
);
4000     switch (base)
4001       {

mpn_limb_size_in_base_2 fails because it expects u to be greater than zero.

1147   static mp_bitcnt_t
1148   mpn_limb_size_in_base_2 (mp_limb_t u)
1149   {
1150     unsigned shift;
1151
1152     assert (u > 0);
1153     gmp_clz (shift, u);
1154     return GMP_LIMB_BITS - shift;
1155   }

I don't really have any ideas right now on a solution either.

Regards,
Austyn



> mpn_set_str_other would then return a value greater than zero for v, even
> if the value is zero.
> Thus v->_mp_size would be greater than zero:
>
> 4179       rn = mpn_set_str_other (rp, dp, sn, base, &info);
> 4180     }
> 4181   assert (rn <= alloc);
> 4182   gmp_free (dp);
> 4183
> 4184   r->_mp_size = sign ? - rn : rn;
>
> As a consequence, mpz_sgn(v) would return 1.
>
> Kind regards
> Axel
>
>
>
> Von:        Austyn Krutsinger <akrutsinger at gmail.com>
> An:        Torbjörn Granlund <tg at gmplib.org>
> Kopie:        Axel Miller <axel.miller at ppi.de>, gmp-bugs at gmplib.org
> Datum:        21.07.2016 10:53
> Betreff:        Re: mini-gmp: mpz_init_set_str fails on leading zeroes
> ------------------------------
>
>
>
>
> On Thu, Jul 21, 2016 at 1:43 AM, Torbjörn Granlund <*tg at gmplib.org*
> <tg at gmplib.org>> wrote:
> Austyn Krutsinger <*akrutsinger at gmail.com* <akrutsinger at gmail.com>>
> writes:
>
>   My initial though was to just skip the leading zero's in the mpz_set_str
>   function by something like this:
>
>     while (isspace( (unsigned char) *sp) || (*sp == '0'))
>       sp++;
>
>   Only problems is that this doesn't work for negative numbers that still
>   have a bunch of leading zeros;
>
> I think we should not accept strings like 00000-0000017.
>
> Absolutely agree with you, kind of a silly proposal in retrospect.
>
> We can fix this in the mpn_set_str_other function by changing the
> comparison in line 1321. If we accept that w can be > or = to 0, then there
> is no issue if the number has leading zeros. So line 1321 in
> mpn_set_str_other becomes:
>
> 1321   for (rn = (w >= 0); j < sn;)
> 1322     {
> 1323       mp_limb_t cy;
> 1324
> 1325       w = sp[j++];
> 1326       for (k = 1; k < info->exp; k++)
> 1327     w = w * b + sp[j++];
> 1328
> 1329       cy = mpn_mul_1 (rp, rp, rn, info->bb);
> 1330       cy += mpn_add_1 (rp, rp, rn, w);
> 1331       if (cy > 0)
> 1332     rp[rn++] = cy;
> 1333     }
> 1334   assert (j == sn);
> 1321   for (rn = (w > 0); j < sn;)
>
> Regards,
> Austyn
>
>


More information about the gmp-bugs mailing list