有没有一种简单的方法来确定GMP整数的位数?我知道可以通过对数来确定它,但我想知道库中是否有什么东西我错过了。在手册中我找到的唯一一件事是:
_mp_size表示肢体的数量,或者当表示负整数时为其相反数。如果将_mp_size设置为零,则表示为零,此时_mp_d数据未使用。
但我认为这与我要找的东西相当不同。
即
124839 = 6个数字。
有没有一种简单的方法来确定GMP整数的位数?我知道可以通过对数来确定它,但我想知道库中是否有什么东西我错过了。在手册中我找到的唯一一件事是:
_mp_size表示肢体的数量,或者当表示负整数时为其相反数。如果将_mp_size设置为零,则表示为零,此时_mp_d数据未使用。
但我认为这与我要找的东西相当不同。
即
124839 = 6个数字。
您可以使用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返回的值大两个单位,一个用于负号,另一个用于字符串结尾的null字符。
因此,类似以下内容:
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风格打印的技巧。
请注意,这两种“确切大小”的解决方案都包括可选符号在前面。如果您想真正计算数字而非字符的数量,则应进行调整(例如,如果数字小于零,则从大小中减去一)。
sizeinbase()+2
来分配足够的空间,将值输出到该缓冲区中,并使用 strlen()
进行操作。 - paxdiablosnprintf
也是如此。你在两种情况下都出现了核心转储,这事实支持了这一点-几乎肯定是代码有问题。如果你想发帖提问并附上代码,你会得到比留下必要截断的评论更多的帮助。 - paxdiablo