Is there a limit to the size of a BigInt or BigUint in Rust?
Rust中num板条箱中的BigInt或BigUint的大小是否没有限制?我看到在Java中,它的长度受整数Integer.MAX_VALUE的上限限制,因为它存储为int数组。
我确实浏览了文档,但无法真正推断出我从
A BigUint-typed value BigUint { data: vec!(a, b, c) } represents a
number (a + b * big_digit::BASE + c * big_digit::BASE^2).
big_digit::BASE的答案依次定义为
1
| pub const BASE: DoubleBigDigit = 1 << BITS |
BITS是32
所以BigInt表示为(a + b * 64 + c * 64^2)内部?
- 无论如何,这是理论上的限制,因为我看不到使用2^u64::MAX这样的大数字
- BigInt被表示为(a + b * 2^32 + c * (2^32)^2),因此限制非常大
TL; DR:可以表示的最大数字大致为:
1
| 3.079 x 10^22212093154093428519 |
我想没有什么有用的东西需要这么大的数字来表示。您可以确定num_bigint可以完成此任务,无论您使用它的用途如何。
理论上,num大整数大小没有限制,因为文档对此没有说明(版本0.1.44)。但是,我们可以计算出一个具体的限制:
BigUint是Vec<BigDigit>,而BigDigit是u32。据我所知,Rust没有为Vec定义最大大小,但是由于最大可能分配的大小是isize::MAX,所以BigDigit aka u32的最大数目是:
1
| MAX_LEN = isize::MAX / sizeof(u32) |
使用此信息,我们可以推断出当前实现中的num::BigUint(以及num::BigInt)最大值为:
1
| (u32::MAX + 1) ^ MAX_LEN - 1 = 2^32^MAX_LEN - 1 |
为使该公式成立,我们模仿了我们计算u8::MAX的方式,例如:
- bit::MAX是1,
- 长度是8,
- ,所以最大值是
这是num文档给出的公式的完整演示:
1
| a + b * big_digit::BASE + c * big_digit::BASE^2 + ... |
如果采用最大值,则为a == b == c == u32::MAX。我们将其命名为a。为了方便起见,我们将其命名为big_digit::BASE b。因此,最大数为:
1
| sum(a * b^n) where n is from 0 to (MAX_LEN - 1) |
如果分解,我们得到:
1
| a * sum(b^n) where n is from 0 to (MAX_LEN - 1) |
x^n之和的一般公式为(x^(n + 1) - 1) / (x - 1)。因此,由于n是MAX_LEN - 1,结果是:
1
| a * (b^(MAX_LEN - 1 + 1) - 1) / (b - 1) |
我们用正确的值替换a和b,最大可表示数字是:
1
| u32::MAX * (2^32^MAX_LEN - 1) / (2^32 - 1) |
u32::MAX是2^32 - 1,因此可以简化为:
- 但是(a + b * big_digit::BASE + c * big_digit::BASE^2) @Boiethios呢?这不会按照文档设置上限吗?
- @RajeevRanjan有关最大值的文档是隐式的:它取决于Vec的最大大小。
- @RajeevRanjan不会阻止您使用BigUint { data: vec!(a, b, c, d) }并获取(a + b * big_digit::BASE + c * big_digit::BASE^2 + d * big_digit::BASE^3)。为什么停在4个元素上?实际的限制将受到您拥有的任何内存的限制。
- 实际上,Rust可以分配的最大大小为isize::MAX。见stackoverflow.com/questions/32324794/
- @trentcl我不确定您说什么,但我出错了。我编辑以给出完整的演算,也许我错了,但我认为它更准确。