Petla for o bardzo duzym zakresie

0

Witam.

Mamy taki bardzo prosty program

program bla;

var
i:real;
begin
for i:=0 to 1000 do
writeln (i);
end.

Program nie dziala, chyba, ze zamienie real na integer. Jak zrobic petle od -x do y dla bardzo duzych wartosci, np. typ zmiennej Comp. Czyli od -9.2E18 do 9.2E18, i tak dlugo petla by sie miala wykonac, a druga sprawa musi ominac zero. Cos w stylu* if i=o then i:=i+1* nie chce zadzialac w petli. Chcialem to zrobic za pomoca repeat until, ale nie za bardzo wiem jak je zapetlic.

Musze znaleŹĆ wszystkie liczby spelniajace rownanie ln(x)=k*i, liczba ktora spelnia to rownanie: x=1, k=0. Chcial bym sprawdzic wszystie mozliwosci dla x i k w zakresie comp, pomijajac x=0 poniewaz ln(0) da na blad. Dla integer wygladalo by to tak

program k2;

var
i,k :integer;

begin

for i:= 1 to 1000 do
for k:= 1 to 1000 do
begin
        //writeln (ln(i),' = ',k*i);
        if ln(i) = k*i then writeln ('i=',i,' k=',k);
end;
writeln('koniec');
readln;
end.

1
var x,xp,xk:Real;
//...
  xp:=-9.2E18;
  xk:=9.2E18;
  x:=xp;
  while x<=xk do
  begin
    if x<>0 then
    begin
      //obliczenia, sprawdzenie warunku itp
    end;
    x:=x+1;
  end;
0

Zrobilem sobie dwie takie ort!, ale nie do konca chce dzialac. Wyskakuje 207, czyli blad operacji zmiennoprzecinkowej. Program wykona sie 1 raz, i robi blad.

Running "c:\fpc\2.4.2\bin\i386-win32\k3.exe "
blo -9.20000000000000E+018
Runtime error 207 at $004014DA
$004014DA
$004080B1

var
  x,xp,xk: real;
  k,kp,kk: real;
begin
xp:=-9.2E18;
xk:=9.2E18;

kp:=-9.2E18;
kk:=9.2E18;

x:=xp;
k:=kp;
while x<=xk do
begin
if x=0 then x:=x+1;
        writeln('blo ',x);
        while k<=kk do
        begin
                if ln(x) = x*k then writeln ('i=',x,' k=',k);
                writeln('ble ',k);
                k:=k+1;
        end;
end;
writeln ('bla');
x:=x+1;

writeln('koniec');
readln;
end.
0
  1. Sprawdź jaka jest dziedzina funkcji logarytm.
  2. Przetestuj program dla małych zakresów liczbowych żeby zobaczyć jak działa.
0

czy to tp czy delphi
bo może być Int64 albo Extended ew double...

0

Zakładając, że jeden przebieg pętli wykonywałby się 1e-10 sekundy (w rzeczywistości jest to bardzo optymistyczne założenie), to cała taka pętla wykonywałaby się około 1e9 sekund, czyli 30 lat. Jak chcesz poznać tę odpowiedź szybciej radziłbym zmienić podejście. Dodatkowo dla liczb podwójnej precyzji -9e18=-9e18+1, więc pętla nigdy się nie skończy

0

Zwróćcie uwagę, że zadanie ma rozwiązanie tylko dla liczb dodatnich.

0

Faktycznie, dla duzych zakresow robi sie dluuuuuuuuuuuugo. Zrobilem z zegarkiem dla miliarda-1 robi 5 sek.

Program lnxk;
uses Dos, Crt;
var
  a,b,c,d,a1,b1,c1,d1:word;
  x,xp,xk: real;
  k,kp,kk: real;
  t:real;
begin

write ('Wprowadz zakres dla i od 1 do 9.2E18: ');
readln (xk);
xp:=1;

write ('Wprowadz zakes dla k od 0 do 9.2E18: ');
readln(kk);
GetTime(a,b,c,d);
kp:=0;

x:=xp;
k:=kp;
while x<=xk do
begin
if x=0 then x:=x+1;
        while k<=kk do
        begin
                if ln(x) = x*k then writeln ('i=',x:1:0,' k=',k:1:0);
                k:=k+1;
        end;

x:=x+1;
end;
GetTime(a1,b1,c1,d1);
writeln('Czas wykonywania: ',a1*3600+b1*60+c1-a*3600-b*60-c,' sekund');
readln;
end.

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