【问题标题】:Finding the 1500000th Fib Number Using C++使用 C++ 查找第 1500000 个 Fib 数
【发布时间】:2011-08-21 08:21:09
【问题描述】:

我编写了以下代码来查找第 1500000 个斐波那契数(请忽略可怕的缩进,我在大约 2 分钟内编写了此代码)。我需要它作为字符串。假设这应该有效:

#include <cstdlib>
#include <iostream>
#include <sstream>
int i;
int b=1;
int c=2;
using namespace std;

int main(int argc, char *argv[])
{

    int fib=1500000;

for (i=1;i<fib-3;i++){
c=b+c;
b=c-b;
}
   stringstream ss;
   ss << c;
   string d=ss.str();
cout << d << endl;
    system("PAUSE");
    return EXIT_SUCCESS;
}

它经过1500000-3次(每次经过3个数字) 我知道问题是这个数字太大而不能包含在一个 int 中。有什么方法可以让我存储它而不包含它作为一个 int 或文件(因为那会非常低效)?如果是这样,我该怎么做?

【问题讨论】:

  • 您需要所有 250,000 多位的答案都是准确的吗?
  • 是的。我实际上需要每 20,000 个数字。

标签: c++ numbers int fibonacci


【解决方案1】:

使用Bignum library

【讨论】:

  • @jwodder:还不如说“使用 GMP”。
  • @nightcracker:为什么?有一些不错的选择,特别是如果您使用的是 Windows 或许可是一个问题。我想到了 Boost.XInt。
  • 所以没有原生解决方案?
  • @TimeCoder:除了编写自己的 Bignum 库(不是一个好主意)之外,没有。
  • 好吧,你不需要编写一个整个 bignum 库。只是分配、添加和转换为字符串。如果您使用以 10 为基数的表示,则最后一部分不需要除法或任何东西。但如果你能避开它,这不是一条好路线。
【解决方案2】:

如果您需要一个精确的形式,您可以将其他递归关系之一与 bignum 库一起使用:

fib(2*n) = fib(n)^2 + fib(n-1)^2
fib(2*n-1) = fib(n)*(2*fib(n-1)+fib(n))

这应该将所需的计算次数减少到 O(log(n)) 而不是 O(n) 您可以在此处查看基于此的方法的伪代码:nth fibonacci number in sublinear time

请注意,第 n^th 斐波那契数需要大约 n*log(phi)/log(2) = n*0.69 二进制数字来表示,因此 1.5M^th 的精确表示将需要大约 130kb 来表示二进制, 或 300kb 作为字符串(大约为 2^(10000000) 或 10^(300000))


在 n=1500 左右作为双打溢出删除

你可以直接使用双打如下(改编自http://en.wikipedia.org/wiki/Fibonacci_number):

double fib( int n )
{
   static const SQRT_5 = sqrt(5.0);
   static const phi = (1.0+SQRT_5)/2.0;
   return floor( (pow(phi,n)/SQRT_5) + 0.5 );
}

虽然如果您需要每个数字,这将不起作用。 (它只会给出大约第 78 个斐波那契数的每个数字)

【讨论】:

  • 嗯,不错的 hack,但是 AFAIK 斐波那契数是一个整数。
  • 一般不会给出所需的精度,在这种特殊情况下会溢出 DBL_MAX。
  • 实际上比这更糟糕......它在大约第 1500 个斐波那契数处溢出。
  • 但是它应该给出大约第 78 位的准确结果(接近不能精确表示为双精度的最小整数的大小)
猜你喜欢
  • 1970-01-01
  • 2012-01-07
  • 2011-04-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-02
  • 1970-01-01
  • 2014-02-04
相关资源
最近更新 更多