GMP整数的位数

Dar*_*nor 15 c++ integer biginteger gmp

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

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

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

124839 = 6位数.

pax*_*blo 16

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

size_t mpz_sizeinbase(mpz_t op,int base)

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

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

所以有些东西:

size_t sz = mpz_sizeinbase (myNum, 10);
Run Code Online (Sandbox Code Playgroud)

应该是个好的开始.

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

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

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

char oneChar;
int sz = gmp_snprintf (&oneChar, 1, "%Zd", myNum);
Run Code Online (Sandbox Code Playgroud)

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

请注意,这两个那些"确切大小"的解决方案包括位于前部的可选的符号.如果你想真正计算数字而不是字符,你应该调整它(例如,如果数字小于零,则从大小中减去一个).

  • ***注意句子:***`结果将是精确的或1太大.翻译,你不能相信这个价值.我被这个函数固有的一个错误*关掉了...... (3认同)