【问题标题】:Calculating powers of big numbers计算大数的幂
【发布时间】:2012-01-08 12:32:02
【问题描述】:

我正在用 C++ 编写一个程序,我必须计算 n^n 的值,其中 1long long 类型来存储结果,答案也会一直计算到 n=15。 在 n=16 时,出现浮点异常,之后结果显示为负值。谁能告诉我代码有什么问题?

long long c;

c=(long long)n;
for(int i=2;i<=n;i++)
   c*=n;

 cout<<c<<endl;

【问题讨论】:

  • (10^9)^(10^9)。宇宙溢出异常..

标签: c++ long-integer


【解决方案1】:

如果你得到负值,那么你就溢出了变量。您需要使用范围更大的数据类型,足以容纳您要计算的数字。如果您的系统没有这种数据类型(我怀疑long long 与您将获得的一样大),那么您将需要使用 bignum 类。

仔细查看您问题中的数字,我认为许多标准的 bignum 类将无法计算 n=109 的 nn。你确定你把问题写对了吗?

【讨论】:

  • n^n for 10^9 是一个非常大的数字。除非你有很多 RAM,否则即使是大整数类型也无法容纳它。
  • @istrandjev 是的,我刚刚开始考虑这个问题。我猜 Anant 错误地抄写了这个问题。
  • (10^9)^(10^9)=10^(9*10^9) 是 90 亿个十进制数字。这将需要大约 3.75GB 的内存来以二进制表示法表示。打印答案需要大约 200 万张纸。
  • 我同意并且我已经指出我的回答中的数字很大。但是我不想生活在一个原子数少于 10^10 的宇宙中,因为这会让人觉得有点太舒服了。
  • @MartinJames 指数只有 10 位数字。 (a^b)^c = a^(bc)。取 a=10,b=9,c=10^9。
【解决方案2】:

long long 类型有 64 位并且是有符号的。这意味着您可以在其中存储的最大数字是 263 - 1。您要计算的数字是 1616,即 (24 )16=264 因此不适合long long。

尝试使用浮点类型double,但结果会不准确。

【讨论】:

  • long long 并不总是有 64 位,但显然它在这个特定的平台上。
  • 没错,C99 要求它有 至少 64 位,但是是的,这里肯定是 64。
【解决方案3】:

现在您已经给出了实际问题的链接(顺便说一句,给出的链接无法正确打开,因为它最后有一个 ']' 所以对于任何感兴趣的人来说here 是一个工作链接)我可以提出一个解决方案为它。

您不需要计算数字本身,您只需计算它的一些属性即可。对于最后 k 位,您只需计算 n^n 除以 10^k 的余数。这可以使用fast exponentiation 在对数时间内完成。对于前 k - k 小于 10 的数字,我的方法如下 - 执行类似快速求幂的操作,但只关心每个中间结果的前 m 位。如果不尝试更高的 m 值,我认为 m=100 应该足以给你正确的答案。这个计算的复杂度是 m 的对数倍。

希望这会有所帮助。

【讨论】:

    【解决方案4】:

    你得到负值是因为 16^16 = 2^64 并且 long long 的范围高达 2^63 - 1。所以你溢出了 long long 类型。没有内置类型可以处理您想要执行的计算,甚至更多:对于 10^9,n^n 的值有 9*10^9 位,几乎不适合常规的内存电脑。你到底想做什么?

    【讨论】:

    • 我正在尝试解决这里给出的问题:[codechef.com/problems/MARCHA4]
    • 我添加了另一个关于如何解决该问题的答案。请看一下。
    【解决方案5】:

    对更大的数进行对数计算。

    log(n^n) = n * log(n)
    

    如果您以 10 为底执行此操作,则可以在屏幕上通过算法打印结果:

    auto res = log10(n) * n;
    auto integer_part = floor(res);
    auto fractional_part = res - integer_part;
    
    auto mantissa = pow(10, fractional_part);
    

    现在mantissa 保存结果的数字,integer_part 保存逗号向右移动的次数。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-05
      • 1970-01-01
      • 2015-07-22
      • 2012-07-06
      • 1970-01-01
      • 1970-01-01
      • 2020-04-19
      相关资源
      最近更新 更多