Количество цифр цельного числа GMP

Есть ли простой способ определить количество цифр, которое имеет целое число GMP? Я знаю, что вы можете определить его через журнал, но мне было интересно, есть ли что-то в библиотеке, которое мне не хватает. Единственное, что я нашел в руководстве:

_mp_size Число конечностей или отрицательное значение, представляющее отрицательное целое число.       Zero представлен параметром _mp_size, равным нулю, и в этом случае данные _mp_d не используются.

Но у меня такое впечатление, что это совсем не то, что я ищу.

то есть

124839 = 6 цифр.

Ответы

Ответ 1

Вы можете использовать size_t mpz_sizeinbase (mpz_t op, int base), чтобы получить количество символов для вывода числа в виде строки в определенной базе.

size_t mpz_sizeinbase (mpz_t op, int base)

Возвращает размер op, измеренный в количестве цифр в данной базе. база может варьироваться от 2 до 62. Знак op игнорируется, используется только абсолютное значение. Результат будет либо точным, либо 1 слишком большим. Если база равна 2, результат всегда будет точным. Если op равен нулю, возвращаемое значение всегда равно 1.

Эта функция может использоваться для определения пространства, необходимого при преобразовании op в строку. Правильный объем размещения обычно равен двум значениям, возвращаемым mpz_sizeinbase, один дополнительный для знака минус и один для нуль-терминатора.

Итак, что-то вроде:

size_t sz = mpz_sizeinbase (myNum, 10);

должно быть хорошим началом.

Если вы хотите получить точный размер, вы можете использовать это значение, чтобы создать достаточно большой буфер, вывести значение в этот буфер, а затем сделать strlen, чтобы получить более точный размер, например:

size_t sz = mpz_sizeinbase (myNum, 10) + 1; // allow for sign
char *buff = malloc (sz + 1);               // allow for `\0`
if (buff != NULL) {
    gmp_sprintf (buff, "%Zd", myNum);
    sz = strlen (buff);
    free (buff);
}

Обратите внимание, что это не самый эффективный способ, поскольку он выделяет буфер каждый раз, когда вы хотите найти длину, и по умолчанию используется самый безопасный размер, если выделение не выполняется, что может быть больше, чем необходимо.

Другим возможным способом является использование более безопасной опции snprintf, так как это возвращает количество байтов, которые были бы написаны, и предотвращает переполнение буфера:

char oneChar;
int sz = gmp_snprintf (&oneChar, 1, "%Zd", myNum);

Я не тестировал это специально, но это трюк, который я использовал для "обычной" печати в стиле C раньше.

Обратите внимание, что оба решения "точного размера" включают в себя необязательный знак спереди. Если вы хотите по-настоящему подсчитать цифры, а не символы, вы должны отрегулировать их (вычитая один из размера, если число меньше нуля, например).

Ответ 2

# Код самообслуживания (код R)

  library(gmp)
  #x <- pow.bigz(5,40) 
  x <- pow.bigz(5,4^9)  #x<- 5^4^3^2
  cat("5^4^3^2, Digits: ",sizeinbase(x, b=10))

5 ^ 4 ^ 3 ^ 2, цифры: 183231