Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/148.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C++ 如何解决大n的斐波那契数的数据溢出问题?_C++_Overflow_Fibonacci - Fatal编程技术网

C++ 如何解决大n的斐波那契数的数据溢出问题?

C++ 如何解决大n的斐波那契数的数据溢出问题?,c++,overflow,fibonacci,C++,Overflow,Fibonacci,为了澄清溢出问题,我有下面最简单的代码来使用unsigned _int64类型计算Fn: #include <iostream> using namespace std; int main() { unsigned _int64 f0 = 0, f1 = 1, fn=1; for (unsigned n = 2; n < 101;n++ ) { fn = f1 + f0; f0 = f1; f1 = fn;

为了澄清溢出问题,我有下面最简单的代码来使用unsigned _int64类型计算Fn:

#include <iostream>
using namespace std;
int main() {
    unsigned _int64 f0 = 0, f1 = 1, fn=1;
    for (unsigned n = 2; n < 101;n++ ) {
        fn = f1 + f0;
        f0 = f1;
        f1 = fn;        
        cout << "F" <<n<<" = "<< fn <<endl; 
    }
    return 0;
}

所以,数学对你打击很大。问题是斐波那契数列的值在快速增长

使用,您可以计算第94个斐波那契数已达到64位无符号长码的最大值

你需要其他方法。例如:

#include <iostream>
#include <array>
#include <algorithm>

constexpr size_t MaxDigits = 250'000u;

using Big = std::array<unsigned char, MaxDigits>;
std::array< Big, 3> f{};

int main() {

    size_t index = 100000u;

    std::array<size_t, 3> sf{};
    std::array<size_t, 3> indexF{ 0,1,2 };

    f[indexF[1]][0] = 1;
    sf[indexF[1]] = 1;
    size_t i{};

    unsigned char carry{};
    while (index--) {

        const size_t indexF0 = indexF[0];
        const size_t indexF1 = indexF[1];
        const size_t indexF2 = indexF[2];

        const size_t sf0 = sf[indexF0];
        const size_t sf1 = sf[indexF1];
        const size_t maxSize = std::max(sf0, sf1);

        for (i = 0; i < maxSize; ++i) {

            const unsigned char f0 = f[indexF0][i];
            const unsigned char f1 = f[indexF1][i];

            const unsigned char sum = carry + f0 + f1;

            (f[indexF2])[i] = sum % 10;
            carry = sum / 10;
        }
        if (carry) {
            f[indexF2][i] = carry--;
            ++sf[indexF2];
        }
        else
            sf[indexF2] = maxSize;

        std::rotate(indexF.begin(), indexF.begin() + 1, indexF.end());
    }
    size_t count{};
    for (int k{ static_cast<int>(sf[indexF[0]]) - 1 }; k >= 0; --k) {
        std::cout << static_cast<int>((f[indexF[0]])[k]);
        ++count;
    }

    std::cout << "\n\nNumber of digits: " << count << "\n\n";
    return 0;
}
#包括
#包括
#包括
constexpr size\u t MaxDigits=250'000u;
使用Big=std::array;
std::arrayf{};
int main(){
尺寸指数=100000u;
std::数组sf{};
std::数组indexF{0,1,2};
f[indexF[1][0]=1;
sf[indexF[1]]=1;
大小{};
无符号字符进位{};
而(索引--){
常数size_t indexF0=indexF[0];
常数size_t indexF1=indexF[1];
常数size_t indexF2=indexF[2];
常数大小为sf0=sf[indexF0];
常数大小为sf1=sf[indexF1];
const size\u t maxSize=std::max(sf0,sf1);
对于(i=0;i=0;--k){

什么是“数据溢出问题”?为什么在这里使用
double
?斐波那契数是整数。使用
int64\t
或某种“bignum”如果你需要更长的数字。我认为长双精度远远不能表示索引为1e7的斐波那契数。此外,对于浮点,像
pow
这样的方法计算几个第一个有效数字。你似乎不明白你在做什么。最后五个数字是你所关心的,为什么您是否在跟踪导致问题的更高数字?1)不要在需要精确结果的整数计算中使用浮点。2)整数
N
的最后5位是
N%100000
。感谢所有评论。我只是用最简单的方式更改了代码,仅用于Fn计算,类型为unsigned\u int64,并显示F94的溢出问题。
#include <iostream>
#include <array>
#include <algorithm>

constexpr size_t MaxDigits = 250'000u;

using Big = std::array<unsigned char, MaxDigits>;
std::array< Big, 3> f{};

int main() {

    size_t index = 100000u;

    std::array<size_t, 3> sf{};
    std::array<size_t, 3> indexF{ 0,1,2 };

    f[indexF[1]][0] = 1;
    sf[indexF[1]] = 1;
    size_t i{};

    unsigned char carry{};
    while (index--) {

        const size_t indexF0 = indexF[0];
        const size_t indexF1 = indexF[1];
        const size_t indexF2 = indexF[2];

        const size_t sf0 = sf[indexF0];
        const size_t sf1 = sf[indexF1];
        const size_t maxSize = std::max(sf0, sf1);

        for (i = 0; i < maxSize; ++i) {

            const unsigned char f0 = f[indexF0][i];
            const unsigned char f1 = f[indexF1][i];

            const unsigned char sum = carry + f0 + f1;

            (f[indexF2])[i] = sum % 10;
            carry = sum / 10;
        }
        if (carry) {
            f[indexF2][i] = carry--;
            ++sf[indexF2];
        }
        else
            sf[indexF2] = maxSize;

        std::rotate(indexF.begin(), indexF.begin() + 1, indexF.end());
    }
    size_t count{};
    for (int k{ static_cast<int>(sf[indexF[0]]) - 1 }; k >= 0; --k) {
        std::cout << static_cast<int>((f[indexF[0]])[k]);
        ++count;
    }

    std::cout << "\n\nNumber of digits: " << count << "\n\n";
    return 0;
}