Ciąg fibonacciego - dla dużych wyrazów

Ciąg fibonacciego - dla dużych wyrazów
P9
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 9 lat
  • Postów:3
0

Jak w temacie, mam za zadanie stworzyć program obliczający dowolny wyraz ciągu fibonacciego. Zakres wyrazów od 0-100000. Mój program oblicza jedynie trochę ponad 23000 wyrazów, a dalej kończy się skala typu danych i nie bardzo mam pomysł jak ten problem rozwiązać.

Kopiuj

#include<iostream>
#include<cstdlib>
#include<iomanip>
using namespace std;
  long double f(int n)
{
	 long double *fib = new  long double[n];

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

	for(int i=2;i<n; i++)
	{
		fib[i] = fib[i-1] + fib[i -2];
	}

	return fib[n-1];
	delete [] fib;

};

int main()
{
	int n;
	cin>>n;
	cout<<setprecision(10000);
	cout<<f(n)<<endl;
	return 0;
};

Patryk27
Moderator
  • Rejestracja:prawie 18 lat
  • Ostatnio:prawie 2 lata
  • Lokalizacja:Wrocław
  • Postów:13042
1

GMP lub własny rodzaj bignumów.
PS

Kopiuj
    return fib[n-1];
    delete [] fib;

Zdajesz sobie sprawę, że delete[] fib nigdy nie zostanie wykonane i masz przez to wyciek pamięci?


bogdans
Moderator
  • Rejestracja:prawie 17 lat
  • Ostatnio:prawie 5 lat
0

To smutne, że głupcy są tak pewni siebie, a ludzie mądrzy - tak pełni wątpliwości. Bertrand Russell
MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:około 3 godziny
2

Nie wiem co masz na myśli pisząc 23000 wyrazów.
long double pozwala na poprawne zapisanie liczby całkowitej o długości 18 dziesiętnych cyfr znaczących.
(Prawie) Wszystkie twoje wyniki dłuższe niż 18 cyfr są tylko przybliżeniem.

Żeby dobrze to policzyć potrzebujesz kod na długie liczby. Tablica intów, gdzie każda komórka trzyma 9 cyfr dziesiętnych, będzie najlepszym rozwiązaniem (jakby obliczenia w systemie o podstawie miliard). Czemu miliard? Bo to jest największa potęga 10, która mieści się w int.
Wykorzystaj dodawanie pisemne, którego uczyli cię w szkole.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
kaczus
warto dodać long double dodatkowo jest zależne od kompilatora/platformy sprzetowej/ustawien i może mieć od 64 bitów, do 128...
P9
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 9 lat
  • Postów:3
0
MarekR22 napisał(a):

Nie wiem co masz na myśli pisząc 23000 wyrazów.
long double pozwala na poprawne zapisanie liczby całkowitej o długości 18 dziesiętnych cyfr znaczących.
(Prawie) Wszystkie twoje wyniki dłuższe niż 18 cyfr są tylko przybliżeniem.

Żeby dobrze to policzyć potrzebujesz kod na długie liczby. Tablica intów, gdzie każda komórka trzyma 9 cyfr dziesiętnych, będzie najlepszym rozwiązaniem (jakby obliczenia w systemie o podstawie miliard). Czemu miliard? Bo to jest największa potęga 10, która mieści się w int.
Wykorzystaj dodawanie pisemne, którego uczyli cię w szkole.

Ok tylko po co to dodawanie, bo tej idei jakoś nie rozumiem.

pingwindyktator
No pewnie dlatego, że cały algorytm to właściwie wyłącznie dodawanie.
MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:około 3 godziny
0

tak dla pewności: czy na pewno twój program ma podać pełną wartość ciągu Fibonacciego dla dużych argumentów (n>90)?
Czy może masz podać tylko pierwsze x cyfr albo ostatnie x cyfr, albo wartość modulo m?
Wbrew pozorom to, są o wiele prostsze problemy.


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
P9
  • Rejestracja:ponad 9 lat
  • Ostatnio:ponad 9 lat
  • Postów:3
0

Oto treść zadania:
Ciąg Fibonacciego zdefiniowany jest w następujący sposób: F1 = 1, F2 = 1, Fn = Fn−2 + Fn−1, dla n > 2.

Napisz program, który otrzymawszy numer wyrazu ciągu obliczy jego wartość.

Wejście:
W pierwszej (i jedynej) linii wejścia znajduje się liczba n (1 ≤ n ≤ 100000) — numer wyrazu ciągu.

Wyjście:
Na wyjściu należy wypisać wartość n-tego wyrazu ciągu.

Przykład

Wejście:
500
Wyjście:
139423224561697880139724382870407283950070256587697307264108962948325571622863290691557658876222521294125

edytowany 1x, ostatnio: PIACHU95
MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:około 3 godziny
1

fib(100000) ma 20898 cyfr.
http://www.wolframalpha.com/input/?i=fibbonacci%28100000%29
Licznie tego przez sumowanie to niezbyt dobry pomysł.
Trzeba skorzystać z właściwości ciągu Fibonacciego. Na polskiej wiki znajdziesz kilka możliwości.
Implementacji wielkich liczb nie unikniesz (chyba, że wolno ci korzystać z zewnętrznych bibliotek).


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
Zobacz pozostałe 5 komentarzy
LukeJL
trzycyfrowa: 111
bogdans
przykładny programista indeksuje od zera
Patryk27
Uważam, że liczba 7 jest jedynie metafizyczną reprezentacją zmienności i bezstanowości świata, który - podobnie jak vi - oparty jest o model tzw. piaskownicy, który to z kolei jest jednym z ciekawszych dzieł Kopernika, zaraz po Romeo i Julia, będących skądinąd ewenementem wśród dżumy i czarnej śmierci, czarnej kawy, czarnego chleba i kontrastowego, białego piasku. A skąd wziął się kontrastowy, biały piasek, zapytasz. Otóż to pytanie kieruj już do twórców PHP, a nie do mnie.
bogdans
Jakie środki dają takie efekty? Też chcę.
Koziołek
7 to nie liczba to stan pamięci
0
MarekR22 napisał(a):

fib(100000) ma 20898 cyfr.
http://www.wolframalpha.com/input/?i=fibbonacci%28100000%29
Licznie tego przez sumowanie to niezbyt dobry pomysł.
Trzeba skorzystać z właściwości ciągu Fibonacciego. Na polskiej wiki znajdziesz kilka możliwości.
Implementacji wielkich liczb nie unikniesz (chyba, że wolno ci korzystać z zewnętrznych bibliotek).

Phi^n/sqrt(5)

zatem dla k cyfr limitem będzie:
log Phi^n/sqrt(5) = n log(Phi) - sqrt5 < k

zatem: n < (k+sqrt(5)) / logPhi
co dla double k = 53 daje:

n < (53 + sqrt5)/logPhi = 79,53

Phi^80/sqrt(5) = 23416728348467685

dla quad około 2 razy więcej cyfr, czyli:
Fib(160) = ...

0
Kopiuj
 Wejście:
500
Wyjście:
139423224561697880139724382870407283950070256587697307264108962948325571622863290691557658876222521294125

N-ty wyraz ciagu Fibannociego i taka kobyła?? Przeciez to ledwie 500-tny wyraz...U mnie wg. mojego programu to daje liczbe 315178285.
Moze to wyjscie to jest suma wszystkich wyrazow do n-tego...

Shalom
  • Rejestracja:ponad 21 lat
  • Ostatnio:około 3 lata
  • Lokalizacja:Space: the final frontier
  • Postów:26433
0

A ten twój program czasem nie przekręca się dla tak dużego inta? ;) Bo to jest przecież 345 bitów. Jak napisałeś to w C i lecisz jakimś 32 czy 64 bitowym intem to wiesz ;]


"Nie brookliński most, ale przemienić w jasny, nowy dzień najsmutniejszą noc - to jest dopiero coś!"
edytowany 1x, ostatnio: Shalom
MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:około 3 godziny
0
Świetny Samiec napisał(a):
Kopiuj
 Wejście:
500
Wyjście:
139423224561697880139724382870407283950070256587697307264108962948325571622863290691557658876222521294125

N-ty wyraz ciagu Fibannociego i taka kobyła?? Przeciez to ledwie 500-tny wyraz...U mnie wg. mojego programu to daje liczbe 315178285.
Moze to wyjscie to jest suma wszystkich wyrazow do n-tego...

Odkopałeś jakiś stary wątek, a go nawet nie przeczytałeś! Może wtedy byś odkrył, że coś nie tak jest z twoim wynikiem.
http://www.wolframalpha.com/input/?i=fibbonacci(500)


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
0

To znaczy, ze ten klasyk ponizej:

Kopiuj
 public static int fibanoci1(int n)
		{
			if (n == 0) {
				return 0;
			} else if (n == 1) {
				return 1;
			}else {
				return fibanoci1 (n - 2) + fibanoci1 (n - 1);
			}
			
		}

...nie dziala dla n > 100..?
Na rekrutacji mialem problem z ciagiem Fibbannociego. Umiem napisac program sumujacy parzyste wyrazy ciagu Fibbanocciego, ale dla duzych liczb, to strasznie dlugo liczy. Nawet iteracyjna wersja kodu, teoretycznie troche szybsza, zwraca jakies dziwne wyniki...jezeli juz cokolwiek wyliczy..

MarekR22
Moderator C/C++
  • Rejestracja:ponad 17 lat
  • Ostatnio:około 3 godziny
1

http://www.wolframalpha.com/input/?i=log(fibbonacci(100))%2Flog(2)
http://www.wolframalpha.com/input/?i=log(fibbonacci(94))%2Flog(2)
http://www.wolframalpha.com/input/?i=log(fibbonacci(93))%2Flog(2)
Czyli największy element ciągu Fibonacciego jaki mieści się w long long unsigned int (64 bity) to 93.
A ty używasz int czyli 31 bitów (liczba ze znakiem) czyli ostatni reprezentowalny element tego ciągu to 46:
http://www.wolframalpha.com/input/?i=log(fibbonacci(46))%2Flog(2)


Jeśli chcesz pomocy, NIE pisz na priva, ale zadaj dobre pytanie na forum.
0
Kopiuj
Czyli największy element ciągu Fibonacciego jaki mieści się w long long unsigned int (64 bity) to 93.
A ty używasz int czyli 31 bitów (liczba ze znakiem) czyli ostatni reprezentowalny element tego ciągu to 46 

Dzieki za wyjasnienie. W takim razie to zadanie na rekrutacji bylo wredne..

Zarejestruj się i dołącz do największej społeczności programistów w Polsce.

Otrzymaj wsparcie, dziel się wiedzą i rozwijaj swoje umiejętności z najlepszymi.