C++ 整数的位数

C++ 整数的位数,c++,integer,biginteger,gmp,C++,Integer,Biginteger,Gmp,有没有一种简单的方法来确定一个整数的位数?我知道你可以通过日志来确定,但我想知道库中是否有我遗漏的东西。我在手册中找到的唯一内容是: _mp_size表示负整数时肢体的数量,或肢体的负数。 零由设置为零的_mp_size表示,在这种情况下_mp_d数据未使用 但我的印象与我所寻找的完全不同 i、 e 124839=6位。您可以使用size\u t mpz\u sizeinbase(mpz\u t op,int base)获取字符数,以将数字输出为特定基数中的字符串 size\u t mpz\u

有没有一种简单的方法来确定一个整数的位数?我知道你可以通过日志来确定,但我想知道库中是否有我遗漏的东西。我在手册中找到的唯一内容是:

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

但我的印象与我所寻找的完全不同

i、 e


124839=6位。

您可以使用
size\u t mpz\u sizeinbase(mpz\u t op,int base)
获取字符数,以将数字输出为特定基数中的字符串

size\u t mpz\u sizeinbase(mpz\u t op,int base)

返回给定基中以位数测量的op大小。基数可以从2到62不等。忽略op的符号,只使用绝对值。结果要么精确,要么太大。如果基数是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样式打印的一个技巧


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

+1回答一个有趣的问题!谢谢,帕斯迪亚布洛。很不幸,GMP没有办法得到确切的答案。我能用它来解决我的问题,但有点像犹太人区。也许我可以用它来测试我是否“几乎”在那里,然后将结果转换为字符串或流并计算其长度?看起来很不雅观,但这是我能想到的唯一一件事。是的,它主要用于计算一根线需要有多大,所以多了一根的可能性并不是那么糟糕。从源代码来看,他们说你可以对头几个肢体进行统计分析(10000..或99999..),但他们认为这对于它的设计目的来说是不必要的。也许你应该咬紧牙关,根据mpz_sizeinbase分配空间,然后将值打印到其中并执行strlen。注意这句话:
结果要么精确,要么太大。转换时,您不能信任此值。我被这个函数固有的一个错误烧坏了……如果你被这个函数烧坏了,那不是因为这个函数是错误的,而是因为你误解了(或者懒得读)文档:-)它没有固有的“一个错误的关闭”,因为它明确地说明了这就是它给你的(错误是指函数未按描述执行,其他任何操作都是实现选择),如果您将此值用于预期目的,则可以信任此值。如果确实需要确切的大小,请使用
sizeinbase()+2
分配足够的空间,将值输出到该缓冲区,然后执行
strlen()
@Kundor,一个是写入的字节数限制,包括终止符,所以我相信代码是正确的。对于
snprintf
,这也是正确的。两种情况下都会出现内核转储的事实支持这一点-几乎可以肯定,代码有问题。如果你想用代码发布问题,你会我得到的帮助比留下(必要的)评论要多。