【问题标题】:C++ Handling big numbersC++ 处理大数字
【发布时间】:2016-06-19 05:58:25
【问题描述】:

好的,我必须为我的 c++ 类做简单的任务。两个函数,第一个是斐波那契序列,第二个是一些随机序列(查找e)。它看起来像这样:

#include <stdio.h>
#include <cstdlib>
#include <string>
#include <math.h>

void fib(int number)
{
    int a=0, b=1;
    printf("%d\n", a); 
    for (; number>0; number--)
    {
        printf("%d\n", b);
        b+=a;
        a = b-a;
    }
}

void e_math(unsigned int number)
{
    for (double n = 1; number>0; number--, n++)
    {
        printf("%f\n", pow((1+1/n), n));
    }
}

int main(int argc, char** argv)
{
    if (std::string(argv[2])=="f") fib(atoi(argv[1])-1);
    if (std::string(argv[2])=="c") e_math(atoi(argv[1])-1);
    else printf("Bad argument\n");
}

所以最后我做了g++ main.cpp -o app;./app 10 f。它工作得很好。但是当我想:嗯,也许让我们检查更大的数字,然后加上 50 就搞砸了。我的意思是它对大约 40 个序列号(用 Python 检查)做得很好,但后来它开始到 printf() 负数等。我想它可能大约是 int 范围。所以我将int a=0, b=1 更改为long long a=0, b=1,但它仍然打印相同(我仍然使用printf("%d..),因为%lld 不起作用

【问题讨论】:

  • 考虑使用 &lt;iostream&gt;std::cout 在 C++ 中显示某些内容,而不是 printf
  • 尝试使用 %I64d 说明符。但是你会在 N = 100 时遇到同样的溢出问题。
  • %lld 确实有效(至少在我的编译器中)。
  • 您的问题是使用%d 打印不是普通int 的内容。看来你已经找到了正确的方法,为什么不用呢?
  • 好的,std::cout 有效,但我有义务在printf() 中执行此操作吗?第二件事。它有效,但仅适用于 80 多个数字。在 Python 中,我可以毫无问题地做 300 次。我可以用 C++ 做吗?

标签: c++ int long-integer


【解决方案1】:

nth Fibonacci number 大约是 1.6^n,对于 n=50 来说是一个很大的数字(它是 53316291173)。您可以将其表示为long,但随着事情呈指数增长,您将无法将大型nFn 存储为原始数据类型(其中Fn 表示n th 斐波那契数):n+1th 斐波那契数大约是nth 斐波那契数的 1.6 倍。

您需要一个大的 int 数据类型来计算大的 Fnn

【讨论】:

  • 1.6^50 比 2^63 小得多(即使不计算也可以知道,因为两个值都较大),因此很容易适应 int64_t
  • 是的,我刚刚意识到这一点。 :) 但是事情是成倍增长的,所以如果你把n 增加一点,那就太大了。
【解决方案2】:

您可以使用来自The GNU Multiple Precision Arithmetic Library 的整数类。这里是C++ Interface的链接。

编辑:同时查看15.7.4 Fibonacci Numbers

【讨论】:

【解决方案3】:

cmets 中有信息告诉您如何正确打印long long,以便您从整个范围中受益。但是,正如他在回答中所说的那样,您不会走得更远(它将在无符号 64 位上循环 n=94)。

如果您想处理更大的斐波那契数(实际上是任意大数),您可以使用boost::multiprecision

例如:

#include <boost/multiprecision/gmp.hpp>  

boost::multiprecision::mpz_int fib(boost::multiprecision::mpz_int number)
{
    boost::multiprecision::mpz_int a=0, b=1;
    for (; number>0; number--)
    {
        b += a;
        a = b-a;
    }
    return a;
}

int main()
{
    std::cout << fib(500);
}

构建时需要与 gmp 链接。例如:

g++ -o fib fib.cc -lgmp
./fib
139423224561697880139724382870407283950070256587697307264108962948325571622863290691557658876222521294125

【讨论】:

    【解决方案4】:

    由于 %lld 不可移植并且在任何编译器中都不起作用,如果将 ab 声明为 long 并使用 c++ std:: 打印结果会怎样cout?

    这是必要的,因为第 50 个斐波那契数是 7778742049,它大于典型的最大正整数值(32 位),即 2147483647。

    顺便说一句,你应该删除最后一个else,我不认为在提供参数f时做你想做的事。

    这是code 工作。

    【讨论】:

      猜你喜欢
      • 2012-03-03
      • 2010-09-12
      • 1970-01-01
      • 2013-07-10
      • 1970-01-01
      • 2023-03-16
      • 1970-01-01
      • 1970-01-01
      • 2011-06-27
      相关资源
      最近更新 更多