JavaScriptsMathematik

Primzahlen 2

Ein Zähler, der alle halbe Sekunde die nächste Primzahl anzeigt und dabei immer weiter läuft.

blackman hat dieses Script eingeschickt, das eine Primzahl nach der anderen berechnet und anzeigt. Ihr müsst nichts eingeben und nichts anklicken: Der Zähler läuft von allein los, sobald die Seite geladen ist, und zeigt alle halbe Sekunde die nächste Primzahl an.

Die Zahlen werden dabei immer höher, und zwar ohne Ende — anhalten lässt sich der Zähler nicht, außer man lädt die Seite neu. Je weiter er kommt, desto länger dauert die Suche nach der nächsten Primzahl; anfangs merkt man davon nichts, nach ein paar Minuten sieht man den Zähler spürbar langsamer werden.

Zur Erinnerung: Eine Primzahl ist eine natürliche Zahl größer als 1, die nur durch 1 und durch sich selbst teilbar ist. Die ersten lauten 2, 3, 5, 7, 11, 13, 17, 19, 23. Die 2 ist die einzige gerade Primzahl, und schon Euklid bewies vor über 2000 Jahren, dass es unendlich viele Primzahlen gibt — der Zähler hier hat also tatsächlich nie ein Ziel. Interessant ist, wie das Script prüft: Es teilt jede neue Zahl nur durch die bereits gefundenen Primzahlen und nur so lange, bis deren Quadrat die Zahl übersteigt. Dieser kleine Kniff spart den allergrößten Teil der Rechenarbeit.

Wenn ihr Primzahlen lieber gezielt sucht statt zuzusehen, schaut euch Primzahlen und Primzahlen innerhalb eines Wertebereichs an. Verwandt sind außerdem die Primfaktorzerlegung, die Teiler einer Zahl und die Goldbachzahl.

Mathematik Baujahr 2008 läuft in deinem Browser

Der Zähler läuft von allein und lässt sich nicht anhalten — ein Neuladen der Seite beginnt wieder bei der 2.

Eingesandt von blackman

So funktioniert das Script

Das Script besteht aus einer einzigen Funktion, die sich selbst immer wieder aufruft. Sie prüft eine Zahl auf Primzahleigenschaft; ist die Zahl prim, wird sie angezeigt und nach einer halben Sekunde geht es mit der nächsten weiter, ist sie es nicht, wird sofort die nächste Zahl geprüft. Ganz nebenbei sammelt das Script alle gefundenen Primzahlen in einer Liste — die braucht es zum Prüfen selbst.

const primzahlen = [2];
let n = 3;

Der Startpunkt. In der Liste primzahlen steht schon die 2, denn sie ist die kleinste Primzahl und lässt sich mit dem Verfahren unten nicht herleiten. n ist die Zahl, die als nächstes geprüft wird. Der Unterschied zwischen const und let: n wird immer wieder verändert und braucht deshalb let; die Liste selbst wird nie durch eine andere ersetzt, nur ergänzt — dafür genügt const.

for (let i = 0; primzahlen[i] * primzahlen[i] <= n; i++) {
  if (n % primzahlen[i] === 0) {
    istPrim = false;
    break;
  }
}

Das ist die Primzahlprüfung und zugleich der klügste Teil des Scripts. Der Prozentoperator % liefert den Rest einer Division; ist er null, geht die Division glatt auf und die Zahl hat einen Teiler — sie ist damit keine Primzahl, break bricht die Schleife sofort ab.

Zwei Abkürzungen stecken in der Schleifenbedingung. Erstens wird nur durch bereits gefundene Primzahlen geteilt, nicht durch alle Zahlen: Wer nicht durch 2 teilbar ist, ist auch nicht durch 4, 6 oder 8 teilbar. Zweitens hört die Prüfung auf, sobald das Quadrat des Teilers größer als n wird. Das ist mathematisch sauber: Hätte n einen Teiler oberhalb seiner Wurzel, müsste es auch einen darunter geben — und den hätte die Schleife längst gefunden. Für die Prüfung der 97 genügen deshalb die Teiler 2, 3, 5 und 7.

if (istPrim) {
  ausgabe.textContent = n;
  primzahlen.push(n);
  n++;
  setTimeout(naechste, 500);
} else {
  n++;
  naechste();
}

Hier trennen sich die Wege. War die Zahl prim, wird sie angezeigt, mit push hinten an die Liste angehängt — künftige Prüfungen nutzen sie als Teiler — und der Zähler rückt weiter. setTimeout(naechste, 500) ruft die Funktion nach 500 Millisekunden erneut auf; das ist die halbe Sekunde Pause, die man beim Zusehen bemerkt.

War die Zahl dagegen keine Primzahl, gibt es nichts anzuzeigen und nichts abzuwarten: Der Zähler rückt weiter und die Funktion ruft sich sofort selbst auf. Eine Funktion, die sich selbst aufruft, nennt man rekursiv. Das ist hier ungefährlich, weil zwischen zwei Primzahlen nie besonders viele Zahlen liegen.

ausgabe.textContent = primzahlen[0];
setTimeout(naechste, 500);

Diese beiden Zeilen starten das Ganze: Erst wird die 2 angezeigt, dann übernimmt nach einer halben Sekunde die Funktion. Das alte Script schrieb seine Ausgabe noch mit document.write in ein Eingabefeld; heute schreibt man den Text mit textContent in ein Element, das bereits auf der Seite steht.

Zum Anpassen: Das Tempo steckt in der Zahl 500 — setTimeout(naechste, 100) lässt den Zähler fünfmal so schnell laufen. Wollt ihr den Zähler anhalten können, merkt euch den Rückgabewert von setTimeout in einer Variablen und übergebt ihn bei einem Klick an clearTimeout.

Script für die eigene Homepage

Kopiert euch den kompletten Code und fügt ihn an der Stelle eurer Seite ein, an der das Script erscheinen soll. Er läuft ohne weitere Dateien und ohne fremde Server.

Mehr aus der Kategorie Mathematik