GMP 整数位数

发布于 2024-10-18 01:50:34 字数 225 浏览 3 评论 0原文

有没有一种简单的方法可以确定 GMP 整数的位数?我知道您可以通过日志确定它,但我想知道库中是否内置了一些我丢失的东西。我在手册中找到的唯一内容是:

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

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

124839 = 6 位数字。

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:

_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.

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

i.e

124839 = 6 digits.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

旧城空念 2024-10-25 01:50:34

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

size_t mpz_sizeinbase(mpz_t op,int基数)

返回以给定基数中的位数测量的 op 大小。基数可以从 2 到 62 变化。忽略 op 的符号,仅使用绝对值。结果要么是精确的,要么是 1 太大。如果底数是 2 的幂,则结果始终是准确的。如果 op 为零,则返回值始终为 1。

该函数可用于确定将 op 转换为字符串时所需的空间。正确的分配量通常比 mpz_sizeinbase 返回的值多 2 个,另外 1 个用于减号,1 个用于空终止符。

所以类似的事情:

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 风格打印的技巧。

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

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)

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.

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.

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:

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:

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.

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).

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文