Błąd w pierwszym wyrazie ciągu fibonacciego

0

Witam, Poniżej znajduje się funkcja do obliczania n-tego wyrazu ciągu fibonacciego napisana w free pascalu . (1,1,2,3,5,8,13,...)
Czy jest wstanie mi ktoś wyjaśnić dlaczego program dla liczby n=1 podaje bledny wynik (29)?

uses crt;
var g,n:byte;

function fab(n:byte):byte;
var a,b,c,i:byte;
begin

a:=1; b:=1; c:=1;

for i:=1 to n-2 do
 begin
  a:=b;
  b:=c;
  c:=a+b;
 end;

fab:=c;
end;

BEGIN
clrscr;

write('Wpisz n: ');
readln(n);
writeln(fab(n));
readkey;
END.
2

Zapewne dlatego że pętlisz do n-2 a jeśli n=1 to jaki jest warunek końca pętli? Zresztą w ogóle źle to teraz liczysz bo powinieneś zacząć od wyrazu zerowego (czy tam minus pierwszego) = 0 i byłoby ok -> miałbyś wtedy (0,1,1,2,...)

0
a,b = 0,1
for i in range(n-1):
   a,b = b,a+b
print("%d-ty wyraz ciągu Fibonacciego = %d" % (n,a))   

a,b = 1,1
for i in range(n-1):
   a,b = b,a+b   
print("%d-ty wyraz ciągu Fibonacciego = %d" % (n,a)) 
0

@emexajt - jeśli pieszesz kod we Free Pascalu to korzystaj z jego dobrodziejstw i puść w niepamięć składnię i możliwości DOSowego, 20-letniego TP; Głównie mam na myśli nieużywanie ukrytej zmiennej Result, wzamian za przypisywanie zwracanej wartości do "nazwy funkcji"; No i typy takie jak Byte czy Integer mają swoje czytelne aliasy, czyli np. UInt8, Int32 itd.;

Co do samego algorytmu - używasz o dwa razy za dużo zmiennych; Jedna już jest zadeklarowana (oczywiście chodzi o Result), natomiast potrzebujesz dwie zmienne - jedna do zapamiętywania wartości poprzedniego wyrazu, a druga służąca za iterator pętli; Aktualnie wyliczony wyraz od razu można zapakować do Result:

function GetFibonacciNumber(AIndex: UInt32): UInt32;
var
  intPrev, intLoop: UInt32;
begin
  if AIndex in [0, 1] then Exit(AIndex);

  intPrev := 0;
  Result := 1;

  for intLoop in [2 .. AIndex] do
  begin
    Result := intPrev + Result;
    intPrev := Result - intPrev;
  end;
end;

Przy czym nadmienić należy, że typ Byte (czy jakikolwiek inny jednobajtowy) nie nadaje się do tej funkcji, bo przekręci się licznik już przy 14-tym wyrazie; A jeśli nie podoba Ci się używanie zmiennej Result to zawsze można zadeklarować sobie dodatkową zmienną, tyle że pod adresem tej ukrytej, za pomocą słówka Absolute:

function GetFibonacciNumber(AIndex: UInt32): UInt32;
var
  intCurr: UInt32 absolute Result;
  intPrev, intLoop: UInt32;
begin
  if AIndex in [0, 1] then Exit(AIndex);

  intPrev := 0;
  intCurr := 1;

  for intLoop in [2 .. AIndex] do
  begin
    intCurr := intPrev + intCurr;
    intPrev := intCurr - intPrev;
  end;
end;

Ale to raczej w ramach ciekawostki.

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