如何计算大数字的位数? C++

Posted

技术标签:

【中文标题】如何计算大数字的位数? C++【英文标题】:How to calculate number of digits on huge number? C++ 【发布时间】:2017-08-06 19:30:15 【问题描述】:

所以我遇到的问题是有两个整数 (a, b) 在 [1, 10^16] 区间内,我需要找出数字 a^b 有多少位?这些数字太大了,无法将它们保存在单个变量上,如果我将它们写在 Array 上,将需要很多时间。

有没有办法用某种公式或比数组更简单的方法来计算 a^b 位数?

【问题讨论】:

10 底对数将给出位数。 您是在寻找一个稍微准确的数字还是一个精确的数字? 我只需要位数,a^b 的实际结果并不重要 【参考方案1】:

在修复 cmets 中建议的一次性错误之后

a^b = floor( b * log(a) ) + 1的位数

【讨论】:

我觉得应该是floor() + 1,否则会给1 10 100等不正确的值。 对于 10 的幂,值将是整数,所以 ceil(n)==n 对所以log(1) == 0, ceil 其中也是0,是不是表示需要0位数才能存1? log(10)==1 等【参考方案2】:

karakfa 说得对。

一个数字n 的底数-k 对数,四舍五入到最接近的整数,将为您提供在底数k 中表示n 所需的位数。

编辑:正如 cmets 中所指出的,它不应该四舍五入,而是向下四舍五入,然后加一。这说明了 10 的整数次方有一个额外的数字。

如果您的号码是 a^b,则取以 10 为底的对数 log a^b 并使用对数定律简化为 b log a。请注意,这种简化发生在 ceiling 函数内部,因此简化是有效的。计算 log a 应该不是问题(它将在 0 到 16 之间)并且 b 是已知的。只需确保在乘法之后而不是之前进行四舍五入。

请注意,浮点数的有限精度可能会在此方法中引入一些错误。如果b x log a 的真实值与b x log a 的最近浮点表示不同,以至于它们落在整数的不同边上,则该方法将失败。您可能会检测到您何时接近这种情况并以某种方式对其进行补救。

【讨论】:

@GaBoKaS 请参阅 Slava 对 karakfa 答案的评论:它应该是 floor() + 1 而不是 ceiling 以考虑 10 的偶数次方。 顺便说一句,在 32 位系统上计算起来并不容易。所以需要64位系统。【参考方案3】:

您可以使用支持任意大数字的库,例如 GMP。

核心 C++ 语言本身不提供处理如此大量数字的类型。所以要么你使用一个预先存在的库,要么自己写一个(我建议前者——不要重新发明***)。

【讨论】:

这完全是关于计算位数,而不必将数字实际存储在内存中。即使使用 100% 的 RAM,它甚至可能是不可写的。无论如何,您可能需要 GMP 来存储代表位数的数字:D 有没有其他不需要下载任何东西的方式? :)

以上是关于如何计算大数字的位数? C++的主要内容,如果未能解决你的问题,请参考以下文章

大整数加法计算

如何计算大 n 的 2^n?

格式化一个大的double以显示四位有效数字

处理大数字与浮点数

计算各个位数不同的数字个数

java中有关大数的操作