C++ 如何解决大n的斐波那契数的数据溢出问题?
为了澄清溢出问题,我有下面最简单的代码来使用unsigned _int64类型计算Fn: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;
#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;
}