#c #c 11 #math
Вопрос:
Я работаю над функцией, которая считает N-е число из последовательности Фибоначчи.
Я использую этот алгоритм для его вычисления: https://artofproblemsolving.com/wiki/index.php/Binet’s_Formula
Проблема в том, что я работаю с большими числами, и я понятия не имею, как хранить данные, чтобы предотвратить их просчеты и другие ошибки :/
Я видел несколько сообщений в стеке, и люди предлагают разделить числа на части и вычислить их таким образом — я думаю, что это просто временное и своего рода примитивное решение.
Существует ли какой-либо новый, современный и не такой сложный метод хранения больших чисел и работы (включая математические операции) с ними без каких-либо ошибок??
Вот функция:
std::string fibonacci(int n)
{
long double numb = 1 / sqrt(5) * (pow(((1 sqrt(5)) / 2),n) - pow(((1 - sqrt(5)) / 2),n));
return std::to_string(numb);
}
Вот вывод о том, как меняются результаты:
Input: 40
Output: 102334155.000000
Answer: 102334155
Input: 50
Output: 12586269025.000021
Answer: 12586269025
Input: 60
Output: 1548008755920.002930
Answer: 1548008755920
Input: 70
Output: 190392490709135.437500
Answer: 190392490709135
Input: 80
Output: 23416728348467744.000000
Answer: 23416728348467685
Input: 90
Output: 2880067194370825216.000000
Answer: 2880067194370816120
Input: 100
Output: 354224848179263111168.000000
Answer: 354224848179261915075
Комментарии:
1. почему вы используете формулу Бинета? Похоже, что это в основном представляет аналитический интерес, но не совсем хорошо подходит для численных расчетов, потому что есть термин, который намного больше, чем конечный результат, и он основан на плавающих точках
2. кстати, у бедняги большая библиотека номеров
std::string
. Вы можете избежать переполнения, выполняя все операции только со строками так, как вы учили их в школе3. Это похоже на какую-то онлайн-проблему, пожалуйста, предоставьте ссылку на нее, чтобы все требования были понятны.
4. Фибоначчи можно представить в виде матрицы, тогда вычислительный
n
элемент этой последовательности-это просто вычислительнаяn
мощность матрицы((1, 1), (1, 0))
. Похоже, вам придется реализовать сложение и умножение больших чисел.5. Для этого нет встроенного оператора. Вы должны делать это вручную, как вы учили в начальной школе. Возьмите ручку и лист бумаги, чтобы добавить 1224 к 4321. Тщательно продумывайте каждый свой шаг, чтобы прийти к окончательному результату. Затем сделайте то же самое в коде
Ответ №1:
Благодаря советам @463035818_is_not_a_number мне удалось решить эту ошибку — добавить числа в строки, подобные этой:
1
27
59
----
86
Кроме того, я немного изменил свой исходный код:
- Я делаю
i
как статику, чтобы функция не начинала отсчет с самого начала - Вместо постоянно растущего вектора я использовал две строки — для подсчета третьего числа нам нужны только два предыдущих, не более
Вот функция:
//Soln Author: ernikus
#pragma once
#include <iostream>
#include <string>
#include <vector>
void reverseStr(std::string amp;str)
{
int n = str.length();
for (int i = 0; i < n / 2; i )
std::swap(str[i], str[n - i - 1]);
}
int char_to_int(const char character)
{
return (int(character) - 48);
}
std::string fibonacci(int n)
{
static std::string number[2]{ "0", "1" };
const int limit = 201;
if ((n - 1) <= 1)
return number[n - 1];
for (static int i = 2; i <= limit; i )
{
int size1 = number[0].size();
int size2 = number[1].size();
int size = size2;
int diff = size - size1;
std::cout << "Numer1: " << number[0] << "tNumber2: " << number[1] << std::endl;
std::cout << "Size1: " << size1 << "tSize2: " << size2 << "tHigh Size: " << size << "tDiff: " << diff << std::endl;
std::string result{};
bool higher = false;
for (int j = size - 1; j >= 0; j--)
{
int trial{ 0 };
if ((j - diff) >= 0)
{
trial = char_to_int(number[0][j - diff]) char_to_int(number[1][j]);
std::cout << "I.tNum1: " << number[0][j - diff] << "tNum2: " << number[1][j] << std::endl;
}
else
{
trial = char_to_int(number[1][j]);
std::cout << "I.tNum2: " << number[1][j] << std::endl;
}
if (higher == true)
{
trial ;
higher = false;
}
if (trial >= 10)
{
higher = true;
trial -= 10;
}
result = std::to_string(trial);
std::cout << "Trial: " << trial << "tResult: " << result << "tJ: " << j << std::endl;
}
if (higher == true)
{
result = "1";
higher = false;
}
reverseStr(result);
std::cout << i << ". " << result << std::endl;
number[0] = number[1];
number[1] = resu<
if (i == n)
{
i ;
return resu<
}
}
return "0";
}
Результат очень удовлетворительный 🙂
Input: 180
Output: 18547707689471986212190138521399707760
Answer: 18547707689471986212190138521399707760
Correct Answer!
Input: 190
Output: 2281217241465037496128651402858212007295
Answer: 2281217241465037496128651402858212007295
Correct Answer!
Input: 200
Output: 280571172992510140037611932413038677189525
Answer: 280571172992510140037611932413038677189525
Correct Answer!
Input: 222
Output: 11111460156937785151929026842503960837766832936
Answer: 11111460156937785151929026842503960837766832936
Correct Answer!
Input: 1111
Output: 6851462981265369536304298877223231154064355390623195419885661484162849735541256952762360871448156142552148460793441585691068131682370855135019896825808086317430648360941203391832868742715640036246053259136014253626356840914521594989Answer: 6851462981265369536304298877223231154064355390623195419885661484162849735541256952762360871448156142552148460793441585691068131682370855135019896825808086317430648360941203391832868742715640036246053259136014253626356840914521594989Correct Answer!
Input: 11111
Output: 515449135231559341621591189426925989418721609167804403107087312453694294479381404009230187092526675635022414542794904158934368158350216751867828729213516067642461147232232268304004580596220514978296704097915617589481297010691749471374967376304898014174716132125169572206688299944881902864940487579850754037243411123276226268998274067232370656873037885028569262362061989878439356579125363739644638605976667733232134130196207453194213358616463005487086631652051025004934485196108344869244852506414543015664379038338857611347469102943415360234480491921571800239803284078147859161629100936007246749423449323827401152142684138017539299637210829955409666781554035555164800825902557894478979141680264821730580654526990976167873657740460977594388216677737796493623940501749951993194553070912364327001564086186444836587037180810655016948562608480145057901528396467327800369394725748856906177005886944277609832795419082424474419033931754123200248752600310587761729439189440527073799320938597514569967706344559861576816209214912702962065352672071494639021231263782338510241176219316180788341549329905272081790433223099472061887224254193326845457247107409050092252994931668934553671721376871177693036352993174131508107261653495025271505086039171034392185521383307925723081097129536244468148375789733582131797176285225457221029865658845503179175504307577930140222583997281098099332145783930418777810346276337273420733754768191403158839413163368990092771464626510432292314209966950363068432367028332284209840897425718364670733733609565321893240873729315360915814803137552560521106490937691421540344502423323064743545226360364012549367167257038202145921861042955299329942301124074181956428710271876930526019606797077558959445434943166179407403375284366340173639269807373108055388080201746447050804598946499248800891171987624229020766742994219485280547337990630263452898332213470171667603200991268579583095661682595442200149483262133621860660302141160974707437100532341443580636798210704649175613121627855118061762876137389590812891131603206815601843823369210865672605256743142632199819790960079549275267815983406188538500072911327187912330503064073869613282412315795790671452556371408354045852898125070873750632615799469070245720036053071341314252092446074260578417947762296896685389368685659291620443322232933074723685001342680075497489
Answer: 515449135231559341621591189426925989418721609167804403107087312453694294479381404009230187092526675635022414542794904158934368158350216751867828729213516067642461147232232268304004580596220514978296704097915617589481297010691749471374967376304898014174716132125169572206688299944881902864940487579850754037243411123276226268998274067232370656873037885028569262362061989878439356579125363739644638605976667733232134130196207453194213358616463005487086631652051025004934485196108344869244852506414543015664379038338857611347469102943415360234480491921571800239803284078147859161629100936007246749423449323827401152142684138017539299637210829955409666781554035555164800825902557894478979141680264821730580654526990976167873657740460977594388216677737796493623940501749951993194553070912364327001564086186444836587037180810655016948562608480145057901528396467327800369394725748856906177005886944277609832795419082424474419033931754123200248752600310587761729439189440527073799320938597514569967706344559861576816209214912702962065352672071494639021231263782338510241176219316180788341549329905272081790433223099472061887224254193326845457247107409050092252994931668934553671721376871177693036352993174131508107261653495025271505086039171034392185521383307925723081097129536244468148375789733582131797176285225457221029865658845503179175504307577930140222583997281098099332145783930418777810346276337273420733754768191403158839413163368990092771464626510432292314209966950363068432367028332284209840897425718364670733733609565321893240873729315360915814803137552560521106490937691421540344502423323064743545226360364012549367167257038202145921861042955299329942301124074181956428710271876930526019606797077558959445434943166179407403375284366340173639269807373108055388080201746447050804598946499248800891171987624229020766742994219485280547337990630263452898332213470171667603200991268579583095661682595442200149483262133621860660302141160974707437100532341443580636798210704649175613121627855118061762876137389590812891131603206815601843823369210865672605256743142632199819790960079549275267815983406188538500072911327187912330503064073869613282412315795790671452556371408354045852898125070873750632615799469070245720036053071341314252092446074260578417947762296896685389368685659291620443322232933074723685001342680075497489
Correct Answer!