| 
| Autor | Beitrag |  
| BenBE 
          Beiträge: 8721
 Erhaltene Danke: 191
 
 Win95, Win98SE, Win2K, WinXP
 D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
 
 | 
Verfasst: Sa 27.11.04 19: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 
          Beiträge: 1098
 Erhaltene Danke: 13
 
 Win7 geg. WInXP oder sogar Win98
 Rad2007
 
 | 
Verfasst: Sa 27.11.04 19: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 
          
  Beiträge: 5248
 Erhaltene Danke: 2
 
 WIN XP, IE 7, FF 2.0
 Delphi 7, Lazarus
 
 | 
Verfasst: Sa 27.11.04 19: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 
          
  Beiträge: 5248
 Erhaltene Danke: 2
 
 WIN XP, IE 7, FF 2.0
 Delphi 7, Lazarus
 
 | 
Verfasst: Sa 27.11.04 19: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 
          Beiträge: 8550
 Erhaltene Danke: 478
 
 Windows 7, Windows 10
 D7 PE, Delphi XE3 Prof, Delphi 10.3 CE
 
 | 
Verfasst: Sa 27.11.04 20: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 
          
  Beiträge: 5248
 Erhaltene Danke: 2
 
 WIN XP, IE 7, FF 2.0
 Delphi 7, Lazarus
 
 | 
Verfasst: Sa 27.11.04 20:39 
 
Ich habe gesagt, dass wenn er nur die 100.000 Primzahl sucht 10x langsamer ist, als mein Prog. |  |  |  
| GTA-Place 
          
  Beiträge: 5248
 Erhaltene Danke: 2
 
 WIN XP, IE 7, FF 2.0
 Delphi 7, Lazarus
 
 | 
Verfasst: Sa 27.11.04 21:53 
 
1 Million Zahlen in 1.5 Sekunden:
 		                       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 <= 5) then
 begin
 if (Zahl <> 2) AND (Zahl <> 3) AND (Zahl <> 5) then
 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;
 |  												| 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 >= 0) AND (Bis >= 0) AND (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 
          Beiträge: 1098
 Erhaltene Danke: 13
 
 Win7 geg. WInXP oder sogar Win98
 Rad2007
 
 | 
Verfasst: So 28.11.04 11: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:
 		                       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:
 		                       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
 if gefunden<soll then
 begin
 b:=floor(sqrt(gefunden));  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  Christian S.: Code- durch Delphi-Tags ersetzt. |  |  |  
| Phantom1 
          Beiträge: 390
 
 
 
 
 | 
Verfasst: So 28.11.04 11: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:
 		                       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:
 		                       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:
 												| 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:
 
 | varPrimS: Array of Cardinal;
 
 function Prim(Zahl: Cardinal): Boolean;
 var Wurzel: Cardinal; Teiler: PCardinal;
 begin
 Result := True;
 if not odd(Zahl) OR (Zahl <= 5) then
 begin
 if (Zahl <> 2) AND (Zahl <> 3) AND (Zahl <> 5) then
 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 
          
  Beiträge: 5248
 Erhaltene Danke: 2
 
 WIN XP, IE 7, FF 2.0
 Delphi 7, Lazarus
 
 | 
Verfasst: So 28.11.04 11: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:
 		                       Delphi-Quelltext 
 									| 1:
 | SetLength(PrimS, Bis);					 |  In folgendes:
 		                       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 
          Beiträge: 8721
 Erhaltene Danke: 191
 
 Win95, Win98SE, Win2K, WinXP
 D1S, D3S, D4S, D5E, D6E, D7E, D9PE, D10E, D12P, DXEP, L0.9\FPC2.0
 
 | 
Verfasst: So 28.11.04 15: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:
 		                       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    	  | 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    Beweis:
 		                       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: 
 		                       Delphi-Quelltext 
 									| 1:
 | SetLength(PrimS, Bis);					 |  In folgendes:
 
 		                       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 
          
  Beiträge: 5248
 Erhaltene Danke: 2
 
 WIN XP, IE 7, FF 2.0
 Delphi 7, Lazarus
 
 | 
Verfasst: So 28.11.04 15: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 15:40, insgesamt 1-mal bearbeitet
 |  |  |  
| Kroni  
          Beiträge: 720
 
 Win 98, Win ME, Win2k, Win XP
 D3 Pro
 
 | 
Verfasst: So 28.11.04 15: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 
          
  Beiträge: 5248
 Erhaltene Danke: 2
 
 WIN XP, IE 7, FF 2.0
 Delphi 7, Lazarus
 
 | 
Verfasst: So 28.11.04 15: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 
          
  Beiträge: 5248
 Erhaltene Danke: 2
 
 WIN XP, IE 7, FF 2.0
 Delphi 7, Lazarus
 
 | 
Verfasst: So 28.11.04 15:54 
 
		                       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;      if not odd(Zahl) OR (Zahl <= 5) then      begin
 if (Zahl <> 2) AND (Zahl <> 3) AND (Zahl <> 5) then          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;
 |  												| 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);        Bis := StrToInt(BisEdit.Text);
 if Bis > 10 then
 SetLength(PrimS, Trunc(0.4*Bis-(Bis/4)))        else
 SetLength(PrimS, 4);
 
 LPrim := 0;        Z := @PrimS[0];
 if (Von >= 0) AND (Bis >= 0) AND (Von < Bis) then        begin
 Start := GetTickCount;
 for X := Von to Bis do          begin
 if Prim(X) then            begin
 Z^ := X;              Inc(Z);              LPrim := X;            end;
 if X mod 20000 = 0 then            begin
 Application.ProcessMessages;              PrimLab.Caption := 'Aktuelle Primzahl: ' + IntToStr(LPrim);            end;
 end;
 
 Ende := GetTickCount;          DauerLab.Caption := 'Diese Überprüfung hat ' + FloatToStr((Ende - Start) / 1000) + ' Sekunden gedauert.';
 PrimLab.Caption := 'Speichern...';
 Z := @PrimS[0];          PrimF := TStringList.Create;
 for X := 0 to Length(PrimS)-1 do          begin
 if Z^ = 0 then              Break;            PrimF.Add(IntToStr(Z^));            Inc(Z);          end;
 
 PrimF.SaveToFile('Paket.prim');          PrimF.Free;
 PrimLab.Caption := 'Aktuelle Primzahl: ' + IntToStr(LPrim);        end
 else
 ShowMessage('Ungültige Eingabe(n)!');      except
 ShowMessage('Es ist ein Fehler aufgetreten!');      end;
 end;
 |  Überprüfung von 20.000.000 Zahlen in 16 Sekunden.
 Speichern so schnell, das man "Speichern..." gar net sieht. |  |  |  
| Phantom1 
          Beiträge: 390
 
 
 
 
 | 
Verfasst: So 28.11.04 17:03 
 
Hier noch eine möglichkeit, bei der kein Byte im RAM verschwendet wird. Jedoch ist die Suche etwa doppelt so langsam.
 												| 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:
 
 | varPrimS: TMemoryStream;
 
 function Prim(Zahl: Cardinal): Boolean;
 var Teiler, Wurzel: Cardinal;
 begin
 Result := True;
 if not odd(Zahl) OR (Zahl <= 5) then
 begin
 if (Zahl <> 2) AND (Zahl <> 3) AND (Zahl <> 5) then
 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; 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 
          
  Beiträge: 5248
 Erhaltene Danke: 2
 
 WIN XP, IE 7, FF 2.0
 Delphi 7, Lazarus
 
 | 
Verfasst: So 28.11.04 17:11 
 
		                       Delphi-Quelltext 
 									| 1:2:
 3:
 4:
 5:
 6:
 7:
 8:
 9:
 
 |       for X := 0 to Length(PrimS)-1 do          beginApplication.ProcessMessages;
 if Z^ = 0 then              Break;            PrimLab.Caption := 'Speichern... (' + IntToStr(X+1) + ' / ' + IntToStr(Length(PrimS)) + ')';            PrimF.Add(IntToStr(Z^));            Inc(Z);          end;
 |  Beispiel:
 Speichern... (10 / 1000) |  |  |  
| GTA-Place 
          
  Beiträge: 5248
 Erhaltene Danke: 2
 
 WIN XP, IE 7, FF 2.0
 Delphi 7, Lazarus
 
 | 
Verfasst: So 28.11.04 18:34 
 
Neue Statistik:
 Überprüfung von 1.000.000.000 Zahlen in 52 Minuten.
 Das sind 508.475.534 Primzahlen.
 |  |  |  
| AXMD 
          Beiträge: 4006
 Erhaltene Danke: 7
 
 Windows 10 64 bit
 C# (Visual Studio 2019 Express)
 
 | 
Verfasst: So 28.11.04 19:02 
 
@GTA: Sicher, dass du nicht vertippt hast? Das würde ja heißen, dass jede zweite Zahl eine Primzahl ist
 AXMD
 |  |  |  
| GTA-Place 
          
  Beiträge: 5248
 Erhaltene Danke: 2
 
 WIN XP, IE 7, FF 2.0
 Delphi 7, Lazarus
 
 | 
Verfasst: So 28.11.04 19:11 
 
Könnt nur sein, das das falsche Zahlen sind. Ich guck mal nach. |  |  |  |