Is there an option to truncate an mpz_t?

Anders Andersson pipatron at gmail.com
Tue Feb 16 21:05:49 UTC 2021


On Tue, Feb 16, 2021 at 9:48 PM Simon Sobisch <simonsobisch at gnu.org> wrote:
>
> Hi fellow GMP users,
>
> the code to truncate or pad left that I'm currently using has different
> issues, especially when the value stored in mpz_t is quite big as it
> will allocate a huge string which is just freed directly afterwards and
> most of its content not being looked at.
>
> The goal is a fixed-with field (positive integer) in an existing buffer
> [without null termination]; so left-padded with zeroes, or truncated
> (with a marker) on the left side.
>
> The current approach (data buffer and fixed_len are passed to the
> function) is:
>
> char *p = mpz_get_str(NULL, 10, op);
> const size_t size = strlen (p);
> const int diff = fixed_len - size;
> int truncated = 0;
>
> if (diff < 0) {
>     truncated = 1;
>     memcpy (data, p - diff, end_len);
> } else {
>     memset (data, '0', diff);
>     memcpy (data + diff, p, fixed_len);
> }
>
> {
>    void (*freefunc)(void *, size_t);
>    mp_get_memory_functions (NULL, NULL, &freefunc);
>    freefunc (p, strlen(p) + 1);
> }
>
>
> Do you see a better approach in general, maybe even an option to not
> allocate (and fill) a string of possibly 4000 or more bytes just to copy
> the last 4 [if the buffer was very small]?

Not sure if you should really obsess with this, but something like
temp = op % 10^fixed_len:

mpz_ui_pow_ui(m,10,fixed_len);
mpz_mod(temp,op,m);

That should only retain the least "fixed_len" decimals digits. This
could of course be slower than just rendering to a (cached) buffer.


More information about the gmp-discuss mailing list