GMP mpz_sizeinbase returns size 2 for 9 in base 10

2019-07-09 21:29发布

I'm trying to use libgmp and I encountered something strange using mpz_sizeinbase. If I use a number which starts by base - 1 the size is one too big.

#include <gmp.h>
mpz_t n;
int main() {
    unsigned int base = 10;
    mpz_init_set_str (n, "90", base);
    mpz_out_str(stdout, base, n);
    printf(" has length %zu in base %d\n", mpz_sizeinbase (n, base), base);
}

when I run it:

$ gcc -g draft.c -o draft -lgmp && ./draft
90 has length 3 in base 10

Am I doing something wrong?

标签: c gmp
2条回答
ら.Afraid
2楼-- · 2019-07-09 22:30

Note The last statement.

the right amount of allocation is normally two more than the value returned by mpz_sizeinbase, one extra for a minus sign and one for the null-terminator.

size_t mpz_sizeinbase (mpz_t op, int base)

Return the size of op measured in number of digits in the given base. base can vary from 2 to 62. The sign of op is ignored, just the absolute value is used. The result will be either exact or 1 too big. If base is a power of 2, the result is always exact. If op is zero the return value is always 1.

This function can be used to determine the space required when converting op to a string. The right amount of allocation is normally two more than the value returned by mpz_sizeinbase, one extra for a minus sign and one for the null-terminator.

Similar question here worth looking at it

查看更多
The star\"
3楼-- · 2019-07-09 22:34

The kkk's answer already explained the result of mpz_sizeinbase. However, if you want to obtain exact length in decimal base, you can convert it into character array with mpz_get_str and then use strlen from C Standard library (<string.h>):

printf(" has exact length %zu in base %d\n",
    strlen(mpz_get_str(NULL, base, n)), base);

Output:

90 has exact length 2 in base 10

There is one caveat though, for a negative number you may need to substract one, as string representation includes - sign.

查看更多
登录 后发表回答