Thema: Delphi Primzahlen von 0 bis n

Einzelnen Beitrag anzeigen

Benutzerbild von Hador
Hador

Registriert seit: 11. Dez 2004
Ort: Recke
682 Beiträge
 
Turbo Delphi für Win32
 
#1

Primzahlen von 0 bis n

  Alt 28. Sep 2006, 17:21
Ich möchte mit einem Programm alle Primzahlen von 0 und bis zu einer eingegebenen Grenze herausfinden.
An sich klappt das auch ganz gut. Allerdings habe ich dass Problem, dass ich bei einem Durchgang von 0 bis 1.000.000.000 bspw. knapp 1 GB Arbeitsspeicher benötige. Theoretisch könnte ich ja 1/8 des benötigten Rams sparen, wenn ich für jede Boolean-Variable nur ein Bit benötigen würde. (Imho benötigt eine Boolsche Variable bei Delphi 1 Byte.) Allerdings fällt mir dazu keine schnelle Lösung ein. Lediglich:
Delphi-Quellcode:
var
  i: Byte;
...
if i and 1 shl x
...
was aber nicht allzu schnell sein dürfte.

Zusätzlich zu diesem Arbeitsspeicher-Problem würden mich auch noch Vorschläge für Verbesserungen der Geschwindigkeit interessieren. Gern auch in Assambler (Wenn es 'ne ausführliche Erklärung dabei gibt )

Jetzt aber erstmal mein Quelltext (Ich habe ihn mal ein wenig kommentiert):
Delphi-Quellcode:
program Primzahlengenerator;

{$APPTYPE CONSOLE}

uses
  Classes, Windows;

var
  IsPrim: array of Boolean;
  j, k, Max, HalfMax: Int64;
  s: String;
  F: TMemoryStream;
  Time, Time2: Cardinal;
begin
  Writeln('Bitte geben sie eine obere Grenze ein: ');
  Readln(Max);
  Writeln('Bitte geben sie eine Datei an,' +
          ' in der die Primzahlen gespeichert werden sollen:');
  Readln(s);

  Time := GetTickCount;

  SetLength(IsPrim, Max);
    // Länge der Arrays festlegen

  j := 2;
  while j < Max do
  // Vorerst alle Zahlen als Primzahlen markieren
  begin
    IsPrim[j] := True;
    Inc(j);
  end;

  HalfMax := Max div 2;
  // Die Hälfte der Grenze speichern, so dass diese folgend nicht mehr
  // errechnet werden muss

  F := TMemoryStream.Create;

  j := 2;
  while j <= HalfMax do
  // Die halbe Liste durchgehen
  begin
    if IsPrim[j] then
    begin
      F.Write(j, 4);
      // Zahl im MemoryStream schreiben
      k := j shl 1;
      // Startwert ist das doppelte der aktuellen Zahl (j)
      while k < Max do
      begin
        IsPrim[k] := False;
        // Alle Vielfachen der Zahl (j) als Nicht-Prim markieren
        Inc(k, j);
        // k auf das nächste Vielfache setzen
      end;
    end;
    Inc(j);
  end;

  // Die restlichen Primzahlen in den Stream schreiben
  while j < Max do
  begin
    if IsPrim[j] then
      F.Write(j, 4);
    Inc(j);
  end;
  F.SaveToFile(S);
  F.Free;

  // Benötigte Zeit ausgeben
  Time2 := GetTickCount;
  Time := Time2 - Time;
  Write(Time div 60000);
  Write(' Minuten ');
  Write((Time mod 60000) div 1000);
  Write(' Sekunden ');
  Write((Time mod 60000) mod 1000);
  Writeln(' Millisekunden');
end.
PS: Es ist mir klar, dass es schon einige Beiträge zu Primzahlen in der DP gibt, mir geht es jedoch direkt um die Optimierung meines Programms.

EDIT:
Über Bewertungen meines Programmes würde ich mich im übrigen auch freuen.
Lars Kiesow
http://www.larskiesow.de

Computer gehorchen deinen Befehlen, nicht deinen Absichten.
  Mit Zitat antworten Zitat