function TPrimeTime.NumberOfSmallerPrimes(MaximusPrime: Integer): Integer;
var
listOfPrimes: TList; // Liste aller gefundenen Primzahlen
currentNumber: Integer; // Zahl, die wir gerade auf Prim-Eigenschaften prüfen
currentPrimeNumber: Integer; // Primzahl, die wir gerade als Faktor ausschließen wollen
currentPrimeNumberIndex: Integer; // Stelle der Primzahl in der Liste
mightBeAPrime: Boolean; // true, solange wir nciht sicher wissen, dass die Zahl keine Primzahl ist
isAPrime: Boolean; // true, wenn wir sicher wissen, dass die Zahl eine Primzahl ist. Wird nur zum früheren Verlassen der While-Schleife verwendet
primeCounter: Integer; // zählt die Anzahl der gefundenen Primzahlen
maxPossiblePrimeFactor: Real; // kein Primfaktor kann größer sein als diese Zahl
begin
if MaximusPrime <= 0 then begin // ungültige Eingabe
Result := -1;
Exit; // Abbruch
end;
listOfPrimes := TList.Create(); // Liste anlegen
primeCounter := 0; // Bisher haben wir keine Primzahlen gefunden.
for currentNumber := 2 to MaximusPrime - 1 do begin // Wir schauen uns nacheinander alle potentiellen Primzahlen an, die kleiner als MaximusPrime sind
mightBeAPrime := true; // Bleibt true, solange wir nicht beweisen können, dass currentNumber keine Primzahl ist.
isAPrime := false; // Bisher haben wir noch keinen Beweis, dass es sich um eine Primzahl handelt.
currentPrimeNumberIndex := 0; // Wir durchlaufen die Liste der bekannten Primzahlen von Anfang an
maxPossiblePrimeFactor := Sqrt(currentNumber); // Zahlen größer als die Quadratwurzel von currentNumber können keine Primfaktoren sein.
while (currentPrimeNumberIndex < listOfPrimes.Count) and mightBeAPrime and (not isAPrime) do begin // Wir suchen nach einer Primzahl, durch die sich currentNumber teilen lässt.
if (Integer(listOfPrimes.Items[currentPrimeNumberIndex]) > maxPossiblePrimeFactor) then begin // Wir werden keine größeren Primfaktoren mehr finden
isAPrime := true; // die Zahl ist ganz sicher eine Primzahl. Wir verlassen die Schleife frühzeitig, wobei mightBeAPrime noch true ist.
end else if (currentNumber mod Integer(listOfPrimes.Items[currentPrimeNumberIndex])) = 0 then begin
mightBeAPrime := false; // currentNumber ist durch eine Primzahl teilbar, also kann sie selber keine Primzahl sein. Wir können den Test abbrechen.
end;
currentPrimeNumberIndex := currentPrimeNumberIndex + 1; // Mit der nächsten Primzahl weitermachen.
end;
if mightBeAPrime then begin // Wir konnten nicht beweisen, dass es keine Primzahl ist -> Im Zweifel für den Angeklagten.
listOfPrimes.Add(Pointer(currentNumber)); // Die geprüfte Zahl zur Liste der bekannten Primzahlen hinzufügen
primeCounter := primeCounter + 1; // Anzahl der gefundenen Primzahlen erhöhen
end;
end;
listOfPrimes.Free(); // Aufräumen
Result := primeCounter; // Das Ergebnis ist die Anzahl der gefundenen Primzahlen
end;