Pierwsza sprawa to typy danych parametrów procedury i kilka linijek niżej ich:
Kopiuj
Procedure Scraton(f, x, y, xe, eps, hmin);
value xe, eps, hmin;
real x, y, xe, eps, hmin;
label etb;
real function f;
Begin
real E, k1, k2, k3, k4, k5 as real;
boolean fi;
Domyślam się, że x, y, xe, eps i hmin to mają być parametry typu real, etb to etykieta, a f to funkcja przekazywana do procedury Scraton. Są też zmienne lokalne E, k1, k2, k3, k4, k5 typu real oraz jedna fi typu logicznego.
O ile z deklaracją paramtrów i zmiennych lokalnych nie widzę problemu, to jaka ma być początkowa wartość zmiennej fi? Prawda czy fałsz? Bo ta jest używana w warunku zaraz pod jej deklaracją (pomijając tekst w nawiasach, który pewnie jest komentarzem). Obstawiam, że False.
Nie wiem też czy zmiany przeprowadzane na parametrach wejściowych mają mieć globalny zasięg. To co prawda sugeruje sekcja pod etykietą c, ale tego nie jestem pewien.
Wstępna wersja wygląda tak:
Kopiuj
uses
Math;
var
h: real;
type
TRealFunction = function(x, y: real): real;
procedure Scraton(f: TRealFunction; x, y, xe, eps, hmin: real);
var
E, k1, k2, k3, k4, k5: real;
fi: boolean = false;
label
a, b, c;
begin
if fi then
a: begin
E := abs((xe - x) / h);
if E <= 1.5 then fi := E > 1 else goto b;
end;
if fi then h := 0.5 * (xe - x) else h := xe - x;
b: k1 := h * f(x, y);
k2 := h * f(x + 0.222222222222 * h, y + 0.2222222222222 * k1);
k3 := h * f(x + 0.333333333333 * h, y + 0.8333333333333 * k1 + 0.25 * k2);
k4 := h * f(x + 0.75 * h, y + 0.5390625 * k1 - 1.8984375 * k2 + 2.109375 * k3);
k5 := h * f(x + 0.9 * h, y - 0.3105 * k1 + 1.8225 * k2 - 1.1016 * k3 + 0.4896 * k4);
E := (0.34 * k1 - 0.972 * k2 + 1.632 * k4 - k5) * (0.129357298475 * k1 - 0.551470588235 * k2
+ 0.46568627451 * k3 - 0.0435729847494 * k4) / (k4 - k1);
k2 := abs(E);
if k2 > eps then goto c;
y := y - E + 0.104938271605 * k1 + 0.476470588235 * k3 + 0.237037037037 * k4 + 0.181554103123 * k5;
if fi then
begin
x := x + h;
c: h := h * (eps / k2) ** 0.2;
if abs(h) > hmin then goto a else exit;
end;
x := xe;
fi := true;
end;
Kod kompiluje się bez żadnych problemów czy ostrzeżeń. W sumie to niewiele rzeczy trzeba było poprawić, bo składniowo nawet pasował. Nie zmieniałem wielkości liter w identyfikatorach, żeby był podobny do oryginału. Musisz sobie sprawdzić poprawność jej działania. Jednak zastosowałem dwa uproszczenia – o tym niżej.
Nigdzie nie widzę deklaracji h – nie jest to ani zmienna lokalna, ani też parametr. Dlatego zadeklarowałem ją jako zmienną globalną. Jej wartość najpierw ustalana jest w drugim warunku, a następnie używana jest do obliczania wartości dla zmiennych k*, więc nie trzeba jej inicjalizować.
Druga sprawa – etykieta etb nie znajduje się wewnątrz procedury Scraton. Każda lokalnie zadeklarowana etykieta musi być lokalnie użyta, nie może się znajdować w innej procedurze. Dlatego zamieniłem odwołanie się do niej na instrukcję exit, aby w tym miejscu przerwać działanie procedury, bo obstawiam, że tak ma to działać.
No i w Pascalu operator ^ służy do wydłubywania danych spod wskaźnika, więc trzeba było go wymienić. Free Pascal do potęgowania przewiduje operator ** i z tego też skorzystałem. Mam nadzieję, że w tym miejscu faktycznie o potęgowanie chodziło.