Add mpz_inp_str to mini-gmp

Austyn Krutsinger akrutsinger at gmail.com
Wed Jul 6 11:32:24 UTC 2016


On Wed, Jul 6, 2016 at 1:41 PM, Niels Möller <nisse at lysator.liu.se> wrote:

> Austyn Krutsinger <akrutsinger at gmail.com> writes:
>
> > I am not sure if there was a reason FILE streams were not implemented
> > before, but if there is I'd be interested in hearing why.
>
> mpz_out_str is included in mini-gmp, so it would make sense to also
> include the companion function mpz_inp_str.
>
> However, for mini-gmp, we need something considerably simpler than the
> code in mpz/inp_str.c. Which isn't entirely trivial. Ideally, it should
> just read the number and pass it on to mpz_set_str. But to detect the
> end of the number, it first has to parse any base prefix (like "0x"),
> and then look for the first non-digit. And it's no good to have a lot of
> code duplication with mpz_set_str.
>
> I understand your intent. Makes sense for mini-gmp to be trivial and as
simple as possible. I guess I was going off a false assumption that the
code in mini-gmp be a reflection of the main library instead of a simple
implementation with the functionality of the main library.



> Without thinking very long about it, maybe one could get something
> reasonable by extracting the digit logic of mpz_set_str to a helper
> function. We could also consider omitting support for base == 0 for the
> mini-gmp version of mpz_inp_str, if that makes things simpler.
>
> I didn't change anything in mpz_set_str, however all mpz_inp_str does in
input a string into a char * buffer, then passes that buffer to
mpz_set_str. I think the approach is simple enough, but the possible
downside is that the entire string has to be read into memory before being
passed to mpz_set_str, where the entire string has to be read again. I
assume this double reading of the string buffer is why you're pondering
whether the digit logic should come out of mpz_set_str. Below is the
snippet of code that would do the reading from a FILE stream.

int
mpz_inp_str (mpz_t x, FILE *stream, int base)
{
  int c;
  size_t nread = 0;
  size_t size = 1000;

  if (stream == 0)
    stream = stdin;

  char *buf = (char *) gmp_xalloc (size);

  /* Read input until end of file */
  while ((c = getc (stream)) != EOF)
    {
      if (nread >= size - 1)
        {
          /* increase input buffer size */
          size_t old_size = size;
          size += 100;
          buf = (char *) gmp_xrealloc (buf, old_size, size);
        }
      buf[nread++] = c;
    }

  buf[nread++] = '\0';  /* Ensure null terminated string */

  c = mpz_set_str(x, buf, base);
  gmp_free (buf);
  return c;
}


I would like to limit the while loop to the maximum number of digits gmp
can theoretically handle. The only reference I've found to this was an old
email chain (circa 2009) so I don't know how accurate the limit is for
64-bit systems.
https://gmplib.org/list-archives/gmp-bugs/2009-July/001538.html

Thanks,
--Austyn



> Regards,
> /Niels
>
> --
> Niels Möller. PGP-encrypted email is preferred. Keyid C0B98E26.
> Internet email is subject to wholesale government surveillance.
>



-- 

--Austyn


More information about the gmp-devel mailing list