Количество цифр GMP целое - PullRequest
       45

Количество цифр GMP целое

15 голосов
/ 20 февраля 2011

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

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

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

, т.е.

124839 = 6 цифр.

1 Ответ

16 голосов
/ 20 февраля 2011

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

size_t mpz_sizeinbase (mpz_t op, int base)

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

Эта функция может использоваться для определения места, необходимого при преобразовании операции в строку. Правильный размер выделения обычно на два больше, чем значение, возвращаемое 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 раньше.

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

...