GMP整数的位数

时间:2021-12-31 16:48:19

Is there an easy way to determine the number of digits a GMP integer has? I know you can determine it through a log, but I was wondering if there was something built into the library that I'm missing. The only thing I've found in the manual is:

有没有一种简单的方法来确定GMP整数的位数?我知道你可以通过日志来确定它,但我想知道库中是否有一些我缺少的内置物。我在手册中找到的唯一一件事是:

_mp_size The number of limbs, or the negative of that when representing a negative integer. Zero is represented by _mp_size set to zero, in which case the _mp_d data is unused.

_mp_size四肢的数量,或表示负整数时的负数。零由_mp_size设置为零表示,在这种情况下_mp_d数据未使用。

But I'm under the impression that is quite different than what I'm looking for.

但我的印象与我正在寻找的完全不同。

i.e

124839 = 6 digits.

124839 = 6位数。

1 个解决方案

#1


14  

You can use size_t mpz_sizeinbase (mpz_t op, int base) to get the number of characters to output the number as a string in a specific base.

您可以使用size_t mpz_sizeinbase(mpz_t op,int base)来获取要在特定基础中输出数字的字符数。

size_t mpz_sizeinbase (mpz_t op, int base)

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.

返回以给定基数中的位数测量的op大小。 base可以在2到62之间变化。忽略op的符号,只使用绝对值。结果将是精确的或1太大。如果base是2的幂,则结果总是精确的。如果op为零,则返回值始终为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.

此函数可用于确定将op转换为字符串时所需的空间。适当的分配量通常比mpz_sizeinbase返回的值多两个,一个额外用于减号,一个用于空终止符。

So something along the lines of:

所以有些东西:

size_t sz = mpz_sizeinbase (myNum, 10);

should be a good start.

应该是个好的开始。

If you want the exact size, you can use that value to create a big enough buffer, output the value to that buffer, then do a strlen to get the more accurate size, something like:

如果你想要确切的大小,你可以使用该值来创建一个足够大的缓冲区,将值输出到该缓冲区,然后执行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);
}

Note that it's not the most efficient way since it allocates a buffer every time you want to find the length, and it defaults to the safest size if the allocation fails, which could be one larger than necessary.

请注意,这不是最有效的方法,因为它每次要查找长度时都会分配缓冲区,如果分配失败,则默认为最安全的大小,这可能比必要的大。

Another possible way is to use the safer snprintf option, since that returns the number of bytes that would have been written, and prevents buffer overflow:

另一种可能的方法是使用更安全的snprintf选项,因为它返回已写入的字节数,并防止缓冲区溢出:

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

I haven't tested that specifically but it's a trick I've used for "regular" C-style printing before.

我没有特别测试过,但这是我之前用于“常规”C风格打印的技巧。

Note that both those "exact size" solutions include an optional sign at the front. If you want to truly count the digits rather then the characters, you should adjust for that (subtracting one from the size if the number is less than zero, for example).

请注意,这些“精确尺寸”解决方案都包含前面的可选标志。如果你想真正计算数字而不是字符,你应该调整它(例如,如果数字小于零,则从大小中减去一个)。

#1


14  

You can use size_t mpz_sizeinbase (mpz_t op, int base) to get the number of characters to output the number as a string in a specific base.

您可以使用size_t mpz_sizeinbase(mpz_t op,int base)来获取要在特定基础中输出数字的字符数。

size_t mpz_sizeinbase (mpz_t op, int base)

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.

返回以给定基数中的位数测量的op大小。 base可以在2到62之间变化。忽略op的符号,只使用绝对值。结果将是精确的或1太大。如果base是2的幂,则结果总是精确的。如果op为零,则返回值始终为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.

此函数可用于确定将op转换为字符串时所需的空间。适当的分配量通常比mpz_sizeinbase返回的值多两个,一个额外用于减号,一个用于空终止符。

So something along the lines of:

所以有些东西:

size_t sz = mpz_sizeinbase (myNum, 10);

should be a good start.

应该是个好的开始。

If you want the exact size, you can use that value to create a big enough buffer, output the value to that buffer, then do a strlen to get the more accurate size, something like:

如果你想要确切的大小,你可以使用该值来创建一个足够大的缓冲区,将值输出到该缓冲区,然后执行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);
}

Note that it's not the most efficient way since it allocates a buffer every time you want to find the length, and it defaults to the safest size if the allocation fails, which could be one larger than necessary.

请注意,这不是最有效的方法,因为它每次要查找长度时都会分配缓冲区,如果分配失败,则默认为最安全的大小,这可能比必要的大。

Another possible way is to use the safer snprintf option, since that returns the number of bytes that would have been written, and prevents buffer overflow:

另一种可能的方法是使用更安全的snprintf选项,因为它返回已写入的字节数,并防止缓冲区溢出:

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

I haven't tested that specifically but it's a trick I've used for "regular" C-style printing before.

我没有特别测试过,但这是我之前用于“常规”C风格打印的技巧。

Note that both those "exact size" solutions include an optional sign at the front. If you want to truly count the digits rather then the characters, you should adjust for that (subtracting one from the size if the number is less than zero, for example).

请注意,这些“精确尺寸”解决方案都包含前面的可选标志。如果你想真正计算数字而不是字符,你应该调整它(例如,如果数字小于零,则从大小中减去一个)。