Dziwne zachowanie funkcji liczącej n!

Dziwne zachowanie funkcji liczącej n!
Odysseus
  • Rejestracja:prawie 21 lat
  • Ostatnio:ponad 11 lat
0

Oto dwie implementacje algorytmu liczącego n!:

  1. z książki:
Kopiuj
function Silnia(n: Integer): Integer;
begin
  if n <= 0 then
    Result := 1
  else
    Result := Silnia(n-1) * n;
end;
  1. moja:
Kopiuj
function MojaSilnia(n: Integer): Integer;
begin
  if n = 0 then
    Result := 1
  else if n = 1 then
    Exit
  else
    Result := MojaSilnia(n-1) * n;
end;

Mimo, że kompilator wywala ostrzeżenie: Return value of function 'MojaSilnia' might be undefined, obie liczą poprawnie do wartości 12!, ponieważ większe wartości dają wyniki wykraczające poza zakres Integer. Żeby policzyć, np. 15! można zrobić małą modyfikację:

Kopiuj
function Silnia(n: Integer): Int64;
begin
  if n <= 0 then
    Result := 1
  else
    Result := Silnia(n-1) * n;
end;
Kopiuj
function MojaSilnia(n: Integer): Int64;
begin
  if n = 0 then
    Result := 1
  else if n = 1 then
    Exit
  else
    Result := MojaSilnia(n-1) * n;
end;

Kompilator nadal wyrzuca w/w ostrzeżenie i zaczynają się dziać dziwne (?) rzeczy. Pierwsza funkcja liczy poprawnie do wartości 19!, bo na tyle wystarcza typ Int64, druga „wymyśla” takie bzdury, że głowa pęka. Może mi ktoś powiedzieć, co jest grane?


wiem, że nic nie wiem
Wolverine
  • Rejestracja:ponad 21 lat
  • Ostatnio:ponad 6 lat
0
Kopiuj
else if n = 1 then
    Exit

Co ta funkcja niby ma zwrocic dla n==1? Komputer to nie wrozka.


Odysseus
  • Rejestracja:prawie 21 lat
  • Ostatnio:ponad 11 lat
0

No dobra. Tylko czemu obie funkcje liczą dobrze gdy zwracają Integer. Gdy zwracają Int64 to druga się sypie? Kiedyś wyczytałem, że tak należy pisać kod by nie pokazywały się ostrzeżnia, czy komunikaty kompilatora, bo może to spowodować dziwne zachowanie programu. Czy jest to z tym związane? Czy może z tym, co pisze Help: "An integer type represents a subset of the whole numbers. The generic integer types are Integer and Cardinal; use these whenever possible, since they result in the best performance for the underlying CPU and operating system.[...]"


wiem, że nic nie wiem
deus
  • Rejestracja:prawie 21 lat
  • Ostatnio:ponad 12 lat
0

Dlaczego? Bo może i zwracasz int64 ale w kodzie nie operujesz na tego typu liczbach.
Tak, jak zauważył Wolverine, dla n < 2 funkcja ma zwracać 1.
I jeszcze jedno, miło by było użyć rekurencji ogonowej.


I nie udawaj, że rozumiesz.
YD
  • Rejestracja:około 18 lat
  • Ostatnio:prawie 15 lat
0

fakt pozostaje faktem, że gdy n będzie się równało 1 to Rezult = "dupa" ? bo nie widze zwrotu żadnej wartości...

// jesteś trzecią osobą, która to napisała, czytaj może uważnie wszystkie posty? (dop. deus)

"nie liczy sie jak to bedzie zrobione, wazne zeby bylo zrobione" :)

Odysseus
  • Rejestracja:prawie 21 lat
  • Ostatnio:ponad 11 lat
0
york_daro napisał(a)

fakt pozostaje faktem, że gdy n będzie się równało 1 to Rezult = "dupa" ? bo nie widze zwrotu żadnej wartości...

Dziwne zrządzenie losu chciało że dla 0! zwraca 1, 1! zwraca 1, 2! – 2, 3! – 6, 4! – 24, 5! – 120 ... 12! – 479001600, ale wtedy i tylko w tedy, gdy funkcja zwraca typ Integer. Gdy zwraca typ Int64 wyniki są zatrważające. Teraz już wiem, że kołomyję robiło to nieszczęsne

Kopiuj
if n = 1 then
    Exit;

po małej modyfikacji:

Kopiuj
function MojaSilnia(n: Integer): Integer; // function MojaSilnia(n: Integer): Int64
begin
  if n = 0 then
    Result := 1
  else if n = 1 then
  begin
    Result := 1;
    Exit;
  end
  else
    Result := Silnia(n-1) * n;
end;

co sprowadza się do prostszego zapisu

Kopiuj
function MojaSilnia(n: Integer): Integer; //function MojaSilnia(n: Integer): Int64
begin
  if n <= 1 then
    Result := 1
  else
    Result := Silnia(n-1) * n;
end;

ostrzeżenie: Return value of function 'MojaSilnia' might be undefined nie pojawia się i funkcja liczy poprawnie <ort>nie zależnie</ort> od tego czy zwraca typ Integer czy Int64.


wiem, że nic nie wiem

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.