Autor Beitrag
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: Sa 27.11.04 20:23 
Du kannst anstatt Int64 auch den Comp-Typ nehmen. Ich hab unter D5 nur nen Int64 genommen, da der schneller ist.

Integer hab ich weggelassen, da mein Programm zu schnell ist. Da würden sich Ints nicht lohnen bzw. sogar Fehler liefern, weil der Zahlenbereich zu klein ist. ;-)

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
Tilo
ontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 1098
Erhaltene Danke: 13

Win7 geg. WInXP oder sogar Win98
Rad2007
BeitragVerfasst: Sa 27.11.04 20:30 
AXMD hat folgendes geschrieben:
GTA-Place hat folgendes geschrieben:
Wir müssten das Überprüfen mal nach dem Sieb des Eratosthenes probieren.
Wir schreiben alle Zahlen in ein Array und löschen alle Zahlen, die durch 2, 3, 5, 7, 11, 13, 17, 19 und 23 teilbar sind. Alle zahlen die übrigbleiben, sind Primzahlen.


Wenn du obige Zahlenreihe (.., 17, 19, 23, ...) nicht fortführst wirst du bald Zahlen entdecken, die das Sieb "übersieht" ;)

AXMD


Lösung: Alle gefundenen Primzahlen in ein Array ablegen(sollte möglichst nicht dynamisch sein).

Probier mal das hier:

www.nrg.to/fishhead2/primzahlgen_6.exe

Mit dem Programm habe ich es auf meiner Kiste(2,4GHZ) in 30 bis 45 min (je nach Nutzung) bis zur Millionsten Primzahl geschafft.
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Sa 27.11.04 20:35 
www.primzahlen.de/files/theorie/sieb.htm hat folgendes geschrieben:
...
Es folgt die 23. Die Zahl 23 wurde bis jetzt nicht weggestrichen und ist deshalb Primzahl. Wir markieren 23 als Primzahl und streichen nun alle durch 23 teilbaren Zahlen, weil diese nicht Primzahlen sein können. Sie hätten jeweils den Teiler 23. Sie liegen alle auf Geraden.
...
Die Zahlen 24, 25 und 26 sind schon gestrichen. Jetzt ist das Ziel erreicht. Alle noch nicht gestrichenen Zahlen sind Primzahlen
...
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Sa 27.11.04 20:42 
Tilo, das Prog. ist voll lahm!
Um die Primzahl 1.299.709 zu finden (bis dahin sind es laut Prog. 100000 Primzahlen), braucht das Prog. 30 Sekunden. Mein Prog üperprüft 1.299.709 Zahlen in 3 Sekunden.
Gausi
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 8548
Erhaltene Danke: 477

Windows 7, Windows 10
D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
BeitragVerfasst: Sa 27.11.04 21:19 
Er findet aber die 1.000.000ste Primzahl! Und ich vermute mal, dass die etwas größer als 1.299.709 ist...

_________________
We are, we were and will not be.
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Sa 27.11.04 21:39 
Ich habe gesagt, dass wenn er nur die 100.000 Primzahl sucht 10x langsamer ist, als mein Prog.
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: Sa 27.11.04 22:53 
1 Million Zahlen in 1.5 Sekunden:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
function Prim(Zahl: LongInt): Boolean;
var
  Teiler, Wurzel: LongInt;
begin
  Result := True;
  if (not odd(Zahl)) OR (Zahl <= 5then
  begin
    if (Zahl <> 2AND (Zahl <> 3AND (Zahl <> 5then
      Result := False;
    Exit;
  end;
  Teiler := 0;
  Wurzel := Trunc(sqrt(Zahl));
  while (Teiler <= Wurzel) AND (Result) do
  begin
    if Zahl mod PrimS[Teiler] = 0 then
      Result := False;
    inc(Teiler);
  end;
end;

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
procedure TMainForm.StartButClick(Sender: TObject);
var
  Start, Ende: Real;
  X, Z, Step, LPrim: Integer;
begin
  try
    Von := StrToInt(VonEdit.Text);
    Bis := StrToInt(BisEdit.Text);

    SetLength(PrimS, Bis+1);
    Step := 10000;
    LPrim := 0;
    Z := 0;

    if (Von >= 0AND (Bis >= 0AND (Von < Bis) then
    begin
      Start := GetTickCount;

      for X := Von to Bis do
      begin
        if Prim(X) then
        begin
          PrimS[Z] := X;
          LPrim := X;
          Inc(Z);
        end;
        if X = Step then
        begin
          Application.ProcessMessages;
          PrimLab.Caption := 'Aktuelle Primzahl: ' + IntToStr(LPrim);
          inc(Step, 10000);
        end;
      end;

      Ende := GetTickCount;
      DauerLab.Caption := 'Diese Überprüfung hat ' + FloatToStr((Ende - Start) / 1000) + ' Sekunden gedauert.';
    end
    else
      ShowMessage('Ungültige Eingabe(n)!');
  except
    ShowMessage('Es ist ein Fehler aufgetreten!');
  end;
end;
Tilo
ontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic starofftopic star
Beiträge: 1098
Erhaltene Danke: 13

Win7 geg. WInXP oder sogar Win98
Rad2007
BeitragVerfasst: So 28.11.04 12:09 
GTA-Place hat folgendes geschrieben:
Ich habe gesagt, dass wenn er nur die 100.000 Primzahl sucht 10x langsamer ist, als mein Prog.


liegt es vielleicht daran, das ich meine Prim routine mit folgender zeile Starte:
ausblenden Delphi-Quelltext
1:
application.OnIdle:=findprim;					

Dadurch lauft das Programm langsamer.
Ich hatte das Programm schon mal schneller, aber dann wurde der gesamte rechner blockiert und das finde ich nicht gut.

die PrimRoutine ist folgende:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
procedure TForm1.findprim(Sender: TObject; var Done: Boolean);
var
a,b,c:integer;
begin
//repeat
if gefunden<soll then
begin
 b:=floor(sqrt(gefunden)); // Suche wird bis
 for a:=1 to b do          //
  if zutesten-sqr(floor(sqrt(zutesten)))<>0 then
   if (zutesten mod primz[a])= 0
    then begin isprim:=false;break end
    else isprim:=true;
 if isprim=true then
 begin
  gefunden:=gefunden+1;
  primz[gefunden]:=zutesten;
  edit2.text:=inttostr(gefunden);
  edit3.Text:=inttostr(zutesten);

 end;
 zutesten:=zutesten+1;
done:=false;
end;
end;


//Edit: Zeile 10 dient dem Test ob die Zahl eine Quadratzahl ist. Wenn nicht gehen durch das Runden der Wurzel die Kommenstellen weg und ein anschließendes Quadrieren für zu einer anderen Zahl.


Pro Durchlauf wird immer nur eine Primzahl getestet. Daurch wird das Programm zwar langsamer, aber Rechnerfreundlicher.

Moderiert von user profile iconChristian S.: Code- durch Delphi-Tags ersetzt.
Phantom1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 390



BeitragVerfasst: So 28.11.04 12:41 
@GTA-Place: dein Code ist wirklich beeindruckend schnell. Jedoch ist noch ein kleiner Denkfehler drin, wodurch die Haupschleife in der Prim-Function sinnlos mehr durchlaufen muss:

hier der code den ich meine:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  while (Teiler <= Wurzel) AND (Result) do  
  begin  
    if Zahl mod PrimS[Teiler] = 0 then  
      Result := False;  
    inc(Teiler);  
  end;


es sollte so aussehen:
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
  while (PrimS[Teiler] <= Wurzel) AND (Result) do  
  begin  
    if Zahl mod PrimS[Teiler] = 0 then  
      Result := False;  
    inc(Teiler);  
  end;


Desweiteren habe ich mal den Code noch etwas Optimiert, da die Zugriffe auf das Array nicht besonders schnell sind, Pointer sind da effizienter:

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
var
  PrimS: Array of Cardinal;

function Prim(Zahl: Cardinal): Boolean;
var Wurzel: Cardinal; Teiler: PCardinal;
begin
  Result := True;
  if not odd(Zahl) OR (Zahl <= 5then
  begin
    if (Zahl <> 2AND (Zahl <> 3AND (Zahl <> 5then
      Result := False;
    Exit;
  end;
  Teiler := @PrimS[0];
  Wurzel := Trunc(sqrt(Zahl));
  while Teiler^ <= Wurzel do
  begin
    if Zahl mod Teiler^ = 0 then begin
      Result := False;
      Break;
    end;
    Inc(Teiler);
  end;
end;

procedure TForm1.Button1Click(Sender: TObject);
const
  Von = 0;
  Bis = 1000000;
var
  Start, Ende: Single;
  X, LPrim: Cardinal;
  Z: PCardinal;
begin
  SetLength(PrimS, Bis);
  Z := @PrimS[0];
  LPrim := 0;
  Start := GetTickCount;

  for X := Von to Bis do begin
    if Prim(X) then begin
      Z^ := X;
      Inc(Z);
      LPrim := X;
    end;
    if X mod 50000 = 0 then begin
      Application.ProcessMessages;
      Label1.Caption := 'Aktuelle Primzahl: ' + IntToStr(LPrim);
    end;
  end;

  Ende := GetTickCount;
  Label2.Caption := 'Diese Überprüfung hat ' + FloatToStr((Ende - Start) / 1000) + ' Sekunden gedauert.';
end;


Du wirst sehen das man für 1 Million Zahlen nicht mehr 1,5 sekunden braucht, sondern nur noch 0,35 Sekunden!!!!!

mfg
phantom1
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: So 28.11.04 12:54 
Danke.
Jetzt gibt es noch ein Prob. Ich weiß nicht, ob es durch die Pointer weg ist:
Je mehr Primzahlen gespeichert sind, desto mehr "Virtueller Speicher" wird benötigt und das meldet dann Windows.
Ich hab schon gedacht, nach 1000 Primzahlen oder so, die alle in ne Datei zu speichern und dann das Array, bzw. jetzt den Pointer zu leeren. Aber dann ist wahrscheinlich nicht mehr gewährleistet, dass alle Primzahlen gefunden werden, oder?


EDIT: Das hier kann noch optimiert werden:
ausblenden Delphi-Quelltext
1:
SetLength(PrimS, Bis);					

In folgendes:
ausblenden Delphi-Quelltext
1:
SetLength(PrimS, Trunc(0.4*Bis+1));					

Denn:

0,4 * 10 = 4 // Zwischen 0 und 10 sind 4 Primzahlen
0,4 * 100 = 40 // Zwischen 0 und 100 sind weniger als 40 Primzahlen.
0,4 * 100.000 = 40.000 // Unterschied, ob die Länge 100.000 oder 40.000 ist (schneller)
BenBE
ontopic starontopic starontopic starontopic starontopic starontopic starhalf ontopic starofftopic star
Beiträge: 8721
Erhaltene Danke: 191

Win95, Win98SE, Win2K, WinXP
D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
BeitragVerfasst: So 28.11.04 16:12 
Tilo hat folgendes geschrieben:
www.nrg.to/fishhead2/primzahlgen_6.exe

Mit dem Programm habe ich es auf meiner Kiste(2,4GHZ) in 30 bis 45 min (je nach Nutzung) bis zur Millionsten Primzahl geschafft.

LOL: Mein Programm macht die Millionste nach 0,985 Sekunden:
ausblenden PrimProj.exe
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
Bis zu welcher Zahl wollen Sie die Primzahlen ermitteln???
1000000

[...]

Ermitteln der Primzahlen fertig: 1015227 geprüfte Zahlen pro Sekunde

Startzeit: 28.11.2004 14:46:38.218
Endzeit:   28.11.2004 14:46:39.203
----------------------------------
Benötigt:           0 00.00.00.985


Und mein Rechner ist ein AMD K6 mit 1,4GHz und SEHR VIELEN Hintergrundprogrammen :D

GTA-Place hat folgendes geschrieben:
Tilo, das Prog. ist voll lahm!
Um die Primzahl 1.299.709 zu finden (bis dahin sind es laut Prog. 100000 Primzahlen), braucht das Prog. 30 Sekunden. Mein Prog üperprüft 1.299.709 Zahlen in 3 Sekunden.


Naja, mein Programm hat nach 30 Sekunden dann schon einmal (fast) alle True-Colorfarben geprüft :D

Beweis:
ausblenden PrimProj.exe
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
Bis zu welcher Zahl wollen Sie die Primzahlen ermitteln???
16777216

[...]

Ermitteln der Primzahlen fertig: 520224 geprüfte Zahlen pro Sekunde

Startzeit: 28.11.2004 14:58:53.734
Endzeit:   28.11.2004 14:59:25.984
----------------------------------
Benötigt:           0 00.00.32.250

Die gesammelten Daten der Primzahlen werden gespeichert!!!
Es wurden 1077871 Primzahlen gespeichert ...


GTA-Place hat folgendes geschrieben:
Danke.
Jetzt gibt es noch ein Prob. Ich weiß nicht, ob es durch die Pointer weg ist:
Je mehr Primzahlen gespeichert sind, desto mehr "Virtueller Speicher" wird benötigt und das meldet dann Windows.
Ich hab schon gedacht, nach 1000 Primzahlen oder so, die alle in ne Datei zu speichern und dann das Array, bzw. jetzt den Pointer zu leeren. Aber dann ist wahrscheinlich nicht mehr gewährleistet, dass alle Primzahlen gefunden werden, oder?


Ich hab in meinem Programm damit eigentlich keine Probleme. Das einzige was ihr beachten müsst, ist, dass ihr Zugriffe auf den Speichermanager auf ein Minimum reduzieren müsst.

Mein Programm hat, IIRC als ich mal bis 5 Mrd. ermittelt hab etwa 512MB RAM für die ganzen Int64's benötigt, OHNE dass Windows irgendwie gemeckert hätte. Das Problem an den Arrays und dem ständigen neuzuweisen ist, dass der Speicher zu stark fragmentiert und dadurch die Neuzuweisungen SEHR Langsam werden. Deshalb hab ich von Array auf PointerArray umgesattelt, da dadurch der Zugriff zum einen Schneller und zum anderen wesentlich einfacher geht.

Weiterhin wird bei mir nur dann neuer Speicher zugewiesen, wenn dies wirklich notwendig ist. Und wenn dieser Fall eintritt, wird sofort die Speichergröße Verdoppelt, was zwar mit Unter bei 512 MB etwa 4 Sekunden benötigen kann, aber immernoch weniger ist, als wenn ich ständig 64KB anfrage.

GTA-Place hat folgendes geschrieben:
EDIT: Das hier kann noch optimiert werden:
ausblenden Delphi-Quelltext
1:
SetLength(PrimS, Bis);					

In folgendes:
ausblenden Delphi-Quelltext
1:
SetLength(PrimS, Trunc(0.4*Bis+1));					

Denn:

0,4 * 10 = 4 // Zwischen 0 und 10 sind 4 Primzahlen
0,4 * 100 = 40 // Zwischen 0 und 100 sind weniger als 40 Primzahlen.
0,4 * 100.000 = 40.000 // Unterschied, ob die Länge 100.000 oder 40.000 ist (schneller)

Wieso diese Optimierung. Sind nur mehr Berechnungen und machen das Programm nur noch langsamer...

_________________
Anyone who is capable of being elected president should on no account be allowed to do the job.
Ich code EdgeMonkey - In dubio pro Setting.
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: So 28.11.04 16:35 
Warum? Das kann ich dir sagen:

Das Prog. soll 1.000.000 Zahlen prüfen.
0,4 * 1.000.000 = 400.000
Das Prog hat 1.000.000 Zahlen geprüft und in eine Datei geschrieben.

So, jetzt öffnen wir mal die Datei und was sehen wir?:

78479 Primzahlen und
321.503 Mal die Zahl 0


EDIT: Und du hast was falsch verstanden:

Tilo hat folgendes geschrieben:
Mit dem Programm habe ich es auf meiner Kiste(2,4GHZ) in 30 bis 45 min (je nach Nutzung) bis zur Millionsten Primzahl geschafft.

BenBE hat folgendes geschrieben:
Bis zu welcher Zahl wollen Sie die Primzahlen ermitteln???
1000000


Es ist ein Unterschied, ob du die ein Millionste Primzahl finden willst oder eine Million Zahlen prüfen willst.

Und mein Prog. prüft 1.000.000 Zahlen in 0.3 Sekunden, schneller als deins.


Zuletzt bearbeitet von GTA-Place am So 28.11.04 16:40, insgesamt 1-mal bearbeitet
Kroni Threadstarter
ontopic starontopic starontopic starontopic starontopic starofftopic starofftopic starofftopic star
Beiträge: 720

Win 98, Win ME, Win2k, Win XP
D3 Pro
BeitragVerfasst: So 28.11.04 16:37 
Na ja, was man nicht noch alles schneller machen kann....@GTA: gute arbeit, nette gedankengängen haben wir uns da zsuammengereimnt...dzu zwar mehr als ich....aba RESPEKT
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: So 28.11.04 16:41 
Danke.
Jetzt muss ich noch ne Formel finden, damit nicht über 320.000 Mal die 0 in der Datei steht. Vielleicht so:

0.4*Bis-(Bis/4) // Aber nur, wenn Bis größer als 10

PS: Hab im oberen Thread ein Edit.
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: So 28.11.04 16:54 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
function Prim(Zahl: Cardinal): Boolean;
var
  Teiler: PCardinal;
  Wurzel: Cardinal;
begin
  Result := True;    // Result = True
  if not odd(Zahl) OR (Zahl <= 5then    // Ist die Zahl nich ungerade oder kleiner als 5, dann
  begin
    if (Zahl <> 2AND (Zahl <> 3AND (Zahl <> 5then    // Ist die Zahl nicht 2 und nicht 3 und nicht 5, dann
      Result := False;    // Result = False
    Exit;                 // Exit
  end;
  Teiler := @PrimS[0];    // Teiler = @PrimS[0]
  Wurzel := Trunc(sqrt(Zahl));    // Wurzel aus der Zahl
  while Teiler^ <= Wurzel do    // Solange Teiler^ <= Wurzel ist, mache
  begin    
    if Zahl mod Teiler^ = 0 then    // Ist Zahl / Teiler^ = Rest 0, dann
    begin
      Result := False;    // Result = False
      Break;    // Break
    end;
    Inc(Teiler);    // Teiler erhöhen um 1
  end;
end;

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
procedure TMainForm.StartButClick(Sender: TObject);
var
  Start, Ende: Real;
  Z: PCardinal;
  X, LPrim: Cardinal;
  PrimF: TStringList;
begin
  try
    Von := StrToInt(VonEdit.Text);    // Start
    Bis := StrToInt(BisEdit.Text);    // Endwert

    if Bis > 10 then
      SetLength(PrimS, Trunc(0.4*Bis-(Bis/4)))    // Größe des Array: 0.4*Bis-(Bis/4)
    else
      SetLength(PrimS, 4);

    LPrim := 0;    // Letze Prim = 0
    Z := @PrimS[0];     // Gefundene Prims = 0

    if (Von >= 0AND (Bis >= 0AND (Von < Bis) then    // Von >= 0; Bis >= 0; Von < Bis;
    begin
      Start := GetTickCount;    // Start-Zeit

      for X := Von to Bis do    // Schleife: Startwert -> Endwert
      begin
        if Prim(X) then    // Funktion ausführen, wenn Prim dann
        begin
          Z^ := X;    // Prim in Array schreiben
          Inc(Z);    // Z erhöhen um 1
          LPrim := X;    // Letze Prim = X
        end;
        if X mod 20000 = 0 then    // Wenn X : 20.000 = Rest 0, dann
        begin
          Application.ProcessMessages;    // Anwendung aktualisieren
          PrimLab.Caption := 'Aktuelle Primzahl: ' + IntToStr(LPrim);    // Akt. Primzahl anzeigen
        end;
      end;

      Ende := GetTickCount;    // End-Zeit
      DauerLab.Caption := 'Diese Überprüfung hat ' + FloatToStr((Ende - Start) / 1000) + ' Sekunden gedauert.';    // Dauer anzeigen

      PrimLab.Caption := 'Speichern...';    // "Speichern..." anzeigen

      Z := @PrimS[0];    // Z auf 0 stellen
      PrimF := TStringList.Create;    // Stringlist erzeugen

      for X := 0 to Length(PrimS)-1 do    // Von 0 bis Größe des Array
      begin
        if Z^ = 0 then    // Wenn Z^ = 0, dann
          Break;    // Break
        PrimF.Add(IntToStr(Z^));    // Prim in Stringlist schreiben
        Inc(Z);    // Z erhöhen um 1
      end;

      PrimF.SaveToFile('Paket.prim');    // Stringlist speichern
      PrimF.Free;    // Stringlist freigeben

      PrimLab.Caption := 'Aktuelle Primzahl: ' + IntToStr(LPrim);    // Akt. Primzahl anzeigen
    end
    else
      ShowMessage('Ungültige Eingabe(n)!');    // Bei falschen Eingaben, Nachricht anzeigen
  except
    ShowMessage('Es ist ein Fehler aufgetreten!');    // Wenn Fehler auftritt, Nachricht anzeigen
  end;
end;


Überprüfung von 20.000.000 Zahlen in 16 Sekunden.
Speichern so schnell, das man "Speichern..." gar net sieht.
Phantom1
ontopic starontopic starontopic starontopic starontopic starontopic starontopic starontopic star
Beiträge: 390



BeitragVerfasst: So 28.11.04 18:03 
Hier noch eine möglichkeit, bei der kein Byte im RAM verschwendet wird. Jedoch ist die Suche etwa doppelt so langsam.

ausblenden volle Höhe Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25:
26:
27:
28:
29:
30:
31:
32:
33:
34:
35:
36:
37:
38:
39:
40:
41:
42:
43:
44:
45:
46:
47:
48:
49:
50:
51:
52:
53:
54:
55:
56:
57:
58:
59:
60:
61:
62:
63:
64:
65:
66:
67:
68:
var
  PrimS: TMemoryStream;

function Prim(Zahl: Cardinal): Boolean;
var Teiler, Wurzel: Cardinal;
begin
  Result := True;
  if not odd(Zahl) OR (Zahl <= 5then
  begin
    if (Zahl <> 2AND (Zahl <> 3AND (Zahl <> 5then
      Result := False;
    Exit;
  end;
  PrimS.Position:=0;
  PrimS.Read(Teiler, SizeOf(Teiler));
  Wurzel := Trunc(sqrt(Zahl));
  while Teiler <= Wurzel do
  begin
    if Zahl mod Teiler = 0 then begin
      Result := False;
      Break;
    end;
    PrimS.Read(Teiler, SizeOf(Teiler));
  end;
  prims.Position:=prims.Size;
end;

procedure TForm1.Button1Click(Sender: TObject);
const
  Von = 0;
  Bis = 15485863// das ist die 1 millionste Primzahl :-)
var
  Start, Ende: Single;
  X, LPrim: Cardinal;
  PrimF: TStringList;
begin
  PrimS:=TMemoryStream.Create;
  try
    LPrim := 0;
    Start := GetTickCount;
    for X := Von to Bis do begin
      if Prim(X) then begin
        PrimS.Write(X, SizeOf(X));
        LPrim := X;
      end;
      if X mod 50000 = 0 then begin
        Application.ProcessMessages;
        Label1.Caption := 'Aktuelle Primzahl: ' + IntToStr(LPrim);
      end;
    end;
    Ende := GetTickCount;
    Label1.Caption:='Aktuelle Primzahl: ' + IntToStr(LPrim);
    Label2.Caption:='Anzahl der gefundenen Primzahlen: '+ IntToStr(PrimS.Size div 4);
    Label3.Caption:='Diese Überprüfung hat ' + FloatToStr((Ende - Start) / 1000) + ' Sekunden gedauert.';

    PrimF := TStringList.Create;
    PrimS.Position:=0;
    while Prims.Position<>Prims.Size do begin
      PrimS.Read(X, SizeOf(X));
      PrimF.Add(IntToStr(X));
    end;
    PrimF.SaveToFile('Paket.prim');
    PrimF.Free;

  finally
    PrimS.Free;
  end;
end;
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: So 28.11.04 18:11 
ausblenden Delphi-Quelltext
1:
2:
3:
4:
5:
6:
7:
8:
9:
      for X := 0 to Length(PrimS)-1 do    // Von 0 bis Größe des Array
      begin
        Application.ProcessMessages;
        if Z^ = 0 then    // Wenn Z^ = 0, dann
          Break;    // Break
        PrimLab.Caption := 'Speichern... (' + IntToStr(X+1) + ' / ' + IntToStr(Length(PrimS)) + ')';    // "Speichern..." anzeigen
        PrimF.Add(IntToStr(Z^));    // Prim in Stringlist schreiben
        Inc(Z);    // Z erhöhen um 1
      end;


Beispiel:

Speichern... (10 / 1000)
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: So 28.11.04 19:34 
Neue Statistik:

Überprüfung von 1.000.000.000 Zahlen in 52 Minuten.
Das sind 508.475.534 Primzahlen.
AXMD
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
Beiträge: 4006
Erhaltene Danke: 7

Windows 10 64 bit
C# (Visual Studio 2019 Express)
BeitragVerfasst: So 28.11.04 20:02 
@GTA: Sicher, dass du nicht vertippt hast? Das würde ja heißen, dass jede zweite Zahl eine Primzahl ist

AXMD
GTA-Place
ontopic starontopic starontopic starontopic starontopic starontopic starofftopic starofftopic star
EE-Regisseur
Beiträge: 5248
Erhaltene Danke: 2

WIN XP, IE 7, FF 2.0
Delphi 7, Lazarus
BeitragVerfasst: So 28.11.04 20:11 
Könnt nur sein, das das falsche Zahlen sind. Ich guck mal nach.