Ciąg fibonacciego - problem z inf

0

Witam, otóż mam problem z poniższym kodem, wszystko się dobrze wypisuje do czasu 1467 wyrazu ciągu, wtedy wywala inf. Specjalnie porównałem swój kod z jakimś innym, który znalazłem na youtubie - https://youtu.be/Rt1HnMdzINo no i swojego błędu nie widze, prosze o pomoc.

#include <iostream>
#include <iomanip>

using namespace std;

int main()
{
	int UserNumber;
	long double fib[100000];
	cout << "Ilosc wyrazow w ciagu: ";
		cin >> UserNumber;

	
	fib[0] = 1;
	fib[1] = 1;

	for (int i = 2; i < UserNumber; i++)
	{
		fib[i] = fib[i - 1] + fib[i - 2];
	}
	cout << setprecision(10000);
	for (int i = 0; i < UserNumber; i++)
	{
		
		cout <<"Wyraz nr "<<i+1<<" jest rowny "<< fib[i] << endl;
	}
	//cout << fib[UserNumber-1];
	return 0;
}
5

To jest 1467 wyraz ciągu Fibonacciego: 1719425029978049497005760765131538987200678483615334018145432682953208137862919946808553878093544143148359727359208036067108875423089927203926507517835261289719458785291530659167420564314632421139573576876888702857409334418125534851215145674272925078512660034886632065236265025087649009680087023699099520578
Jesteś Pewien, że on się mieści w long double?

1

Jak powyżej, a z Wikipedii: https://en.wikipedia.org/wiki/C_data_types

Real floating-point type, usually mapped to an extended precision floating-point number format. Actual properties unspecified. It can be either x86 extended-precision floating-point format (80 >bits, but typically 96 bits or 128 bits in memory with padding bytes), the non-IEEE "double-double" (128 bits), IEEE 754 quadruple-precision floating-point format (128 bits), or the same as >double. See the article on long double for details.

Czyli zależy, Zelent powinien o tym wspomnieć.

1

U Zelenta wypisywane są wyrazy do trzysetnego. Ty wypisujesz 1467.

1

Jaki kompilator? u mnie twój kod działa nawet dla 10000, czy daje poprawne wyniki i dalszych wyrazów nie sprawdzałem. W C/C++ nie ma z góry określonych "wielkości" typów zmiennych, więc może się okazać że jego i mój log double mieszczą większe liczby niż twój.

1
kq napisał(a):

U Zelenta wypisywane są wyrazy do trzysetnego. Ty wypisujesz 1467.

Jednak troszkę większy:

Czyli 23601 pierwszy, u mnie też 23601 jest największy :-)
Linux, Ubuntu, Thinkpad T430, g++-8 -std=c++17 -O3 -Wall -pedantic -c "%f"

0

Dobra już wszystko jasne, dziękuje za wszystkie odpowiedzi.

3
lion137 napisał(a):

To jest 1467 wyraz ciągu Fibonacciego: 1719425029978049497005760765131538987200678483615334018145432682953208137862919946808553878093544143148359727359208036067108875423089927203926507517835261289719458785291530659167420564314632421139573576876888702857409334418125534851215145674272925078512660034886632065236265025087649009680087023699099520578
Jesteś Pewien, że on się mieści w long double?

Przy czym daaaawno już utracił dokładność lepszą niż do jedynki. Zakres to nie wszystko.

Totalny bezsens projektowania algorytmu wybitnie całkowitoliczbowego na jakichkolwiek double'ach.
Ktoś, kto to proponuje jest żałosnym "programistą", ale "sorry,takie mamy autorytety"

1

Napisałem powyżej, bardzo dyplomatycznie, że pan Zelent powinien był o tym wspomnieć :)

9

Żeby było jasne. Ten filmik jest doskonałym przykładem jak bardzo Zelent nie zna się na rzeczy.
Liczby zmiennoprzecinkowe są zapisane za pomocą mantysy i eksponenty.
Czyli w formie: mantysa * 2^eksponenta.
Precyzja mantysy jest ograniczona do określonej ilości bitów.
Ergo long double pozwala na przechowanie jedynie 18 cyfr dziesiętnych wiodących (znaczących) wyniku.
Czyli to co robi Zelent:

cout << setprecision(10000);

Jest bezsensu i ma jedynie zrobić wrażenie na początkujących.
Obliczanie ciągu Fibonacciego dla dużych liczb jest dużo bardziej skomplikowane.

Dowód dla fib(100): Zelent vs wolframalpha.

      Zelent: 354224848179261915072
wolframalpha: 354224848179261915075

inf jest wypisywane w momencie, kiedy kończy się zakres eksponenty.

1 użytkowników online, w tym zalogowanych: 0, gości: 1