Zum Inhalt springen

Primzahlen: Meta: Überblick

Aus Wikibooks

Primzahlen: Meta


Einleitung

[Bearbeiten]

Dass eine Primzahl eine natürliche Zahl größer eins ist, die nur durch eins und sich selbst teilbar ist, kann man als Eigenschaft der Primzahl bezeichnen. Es ist die Eigenschaft, über die sich die Primzahl definiert. Daneben hat die Primzahl noch eine Menge anderer Eigenschaften. Einige dieser Eigenschaften sind trivial, haben aber Auswirkungen auf Zahlen, die aus diesen Primzahlen zusammengesetzt sind. Andere Eigenschaften treffen auch auf Zahlen zu, die keine Primzahlen sind, und die deswegen nur bedingt als Primzahlkriterium eingesetzt werden können.

Primzahlen der Form 4n+1 und 4n-1

[Bearbeiten]

Außer 2 ist jede Primzahl ungerade und hat deshalb die Form oder . Auf äquivalente Weise könnte man sagen eine ungerade Zahl hat die Form oder , denn . Die beiden möglichen Formen spielen eine unterschiedliche Rolle bei ungeraden, zusammengesetzten natürlichen Zahlen.

Wenn eine solche Zahl die Form besitzt, muss sie eine ungerade Anzahl an Primfaktoren der Form besitzen, also mindestens einen Primfaktor dieser Form.
Eine ungerade natürliche Zahl der Form wiederum hat entweder keine Primfaktoren der Form oder ihre Anzahl ist gerade.
Das lässt sich über folgende Sätze zeigen:
Das Produkt zweier Zahlen der Form hat die Form
Das Produkt zweier Zahlen der Form hat die Form
Das Produkt einer Zahl der Form und einer Zahl der Form hat die Form

Primzahlen der Form 6n+1 und 6n-1

[Bearbeiten]

Primzahlen, die größer als drei sind, haben entweder die Form oder . Statt der Form kann man auch sagen die Zahl sei der Form , denn

Zahlen der Form und sind gerade, also keine Primzahlen. Eine Zahl der Form ist durch 3 teilbar und deshalb ebenso keine Primzahl. So trivial das Ganze ist, hat es doch eine Auswirkung, zum Beispiel auf Carmichael-Zahlen einer bestimmten Form.

Eine Zahl mit drei Primfaktoren
und
ist eine bestimmte Form der Carmichael-Zahl. Dabei kann die Primzahl nur der Form sein, denn für gilt
eine Zahl teilbar durch 3, und deshalb keine Primzahl. Es gilt also:
und
und damit ist die Aussage äquivalent mit dem Satz:
Eine Zahl mit den drei Primfaktoren und ist eine Carmichael-Zahl.


Binomialkoeffizient

[Bearbeiten]

Für eine Primzahl gilt: teilt für alle mit . Warum das so ist und warum die Umkehrung (Wenn für eine natürliche Zahl gilt, dass teilt für alle mit , dann ist eine Primzahl) gilt, lässt sich an der folgenden Überlegung verdeutlichen:

Angenommen man hat eine zusammengesetzte Zahl . Als Beispiel nehmen wir die Zahl . Mit der betrachten wir zwei Fälle, nämlich und . Im ersten Fall ist . Wenn wir den Bruch auskürzen wollen, werden wir feststellen, dass von den Zahlen über dem Bruchstrich nur eine einzige Zahl durch teilbar ist, nämlich die selbst. Daraus folgt, dass die Zahl, die den Bruch repräsentiert, gar nicht durch teilbar sein kann. Das gleiche gilt für . Auch hier ist die einzige Zahl über dem Bruchstrich, die durch teilbar ist, die selbst. Warum ist das so? Weil in einem Produkt aus aufeinander folgenden Zahlen genau eine Zahl durch teilbar sein muss. Bei einer Primzahl trifft dieser Fall genau für zu. Aber dieser Binomialkoeffizient spielt für die Eigenschaft von Primzahlen bezüglich der Binomialkoeffizienten gar keine Rolle.

Babbage und Wolstenholme

[Bearbeiten]

Der kleine Fermat

[Bearbeiten]

Die folgenden Eigenschaften haben mit dem kleinen fermatschen Satz zu tun und haben zu Primzahltests auf Basis von Wahrscheinlichkeiten geführt. Natürliche Zahlen, die keine Primzahlen sind und diese Tests trotzdem bestehen, also aufgrund dieser Tests fälschlicherweise als Primzahlen angesehen werden könnten, sind fermatsche Pseudoprimzahlen.

Der kleine Fermatsche Satz

[Bearbeiten]

Angeblich war chinesischen Mathematikern schon ca. 500 v. Chr. bekannt, dass für jede Primzahl gilt, dass die Zahl teilt. Sie vermuteten allerdings fälschlicherweise, dass auch die Umkehrung stimmt; dass also, wenn die Zahl teilt, dieses eine Primzahl sein muss.

Die Verallgemeinerung

Wenn eine Primzahl ist, dann gilt, dass jedes teilt.

ist nach dem Juristen und Amateur-Mathematiker Pierre de Fermat als kleiner fermatscher Satz bekannt geworden. Benutzt wird aber eher folgende Variante:

Wenn eine Primzahl ist, dann gilt für jedes zu teilerfremde .

Der Satz lässt sich einschränken auf: Wenn eine Primzahl ist, dann gilt für alle dass ist.

Umgekehrt gilt nicht dass eine Zahl , wofür für jedes zu teilerfremde ,unbedingt eine Primzahl ist. Ist keine Primzahl, dann nennt man sie Carmichael-Zahl.

Euler

[Bearbeiten]

Eine etwas stärke Eigenschaft, die sich auf den kleinen fermatschen Satz zurückführen lässt, ist folgende:

Wenn eine Primzahl ist, so gilt für jede zu teilerfremde natürliche Zahl

Es gilt folglich entweder

oder

Diese Folgerung wird Leonhard Euler zugeschrieben.

Es lässt sich beweisen dass im ersten Fall die Zahl modulo ein quadratischer Rest ist, und im zweiten Fall ein quadratischer Nichtrest. Es gilt also die Kongruenz:

.

Dabei ist

das Legendre-Symbol, ein Spezialfall des Jacobi-Symbols, das die gleiche Schreibweise hat, und für Primzahlen p übereinstimmen.

Der Beweis stützt auf der Ergebnisse:

  • Es gibt modulo p genau (p-1)/2 Quadratreste.
  • Die Gleichung hat nicht mehr als (p-1)/2 Lösungen.

Wenn a ein Quadratrest modulo p ist, gilt , also

Es sind also genau die (p-1)/2 Quadratreste wofür gilt Fuer die restliche Zahlen a, die quadratische Nichtreste, gilt:


Ein Beispiel: 7 ist die Primzahl , 2 ist die Basis und 5 die Basis .

Es gilt: , da Quadratzahlen der Form existieren. Es gilt: , da keine Quadratzahlen der Form existieren.

Dass aus bzw. folgt, dass gilt, läßt sich daraus ersehen, dass

und ist.

Miller-Rabin

[Bearbeiten]

Lucas-Theorem

[Bearbeiten]

Für positive natuerliche Zahlen m und n und die Primzahl p gilt:

Darin sind:

und

die Entwicklungen von m und n mit Beziehung zur Basis p.

Wilson

[Bearbeiten]

Der Satz von Wilson besagt, dass eine natürliche Zahl n > 1 dann und nur dann eine Primzahl ist, wenn

Daraus folgt

Giuga

[Bearbeiten]

Lineare Rekursionen

[Bearbeiten]

Perrin-Folge

[Bearbeiten]

Die Perrin-Folge (benannt nach dem Mathematiker R.Perrin) ist wie folgt definiert:

Für die Perrin-Folge gilt nun, wenn eine Primzahl ist, dass durch p teilbar ist.

Die Lucas-Folge Vn (P,Q)

[Bearbeiten]

Die allgemeinen Lucas-Folgen und sind nach dem französischen Mathematiker Édouard Lucas benannt, der sich als erster mit ihnen beschäftigt hat.

Die allgemeine Lucas-Folge ist definiert als diejenigen Folge, wofür

und die für n > 1 den Rekursionsformel

genügt.

Für die Lucasfolge gilt, wenn eine Primzahl ist, dass durch p teilbar ist.

Die Lucas-Folge Un (P,Q)

[Bearbeiten]

Die allgemeine Lucas-Folge ist definiert als diejenige Folge, wofür

und die für n > 1 den Rekursionsformel

genügt.

Wie im Vorwort schon erwähnt, lässt sich eine Primzahl als eine natürliche Zahl größer 1, die nur durch 1 und sich selbst teilbar ist, definieren. Aufgrund dieser Eigenschaft existiert der naive Primzahlentest, bei der eine Zahl auf die Teilbarkeit durch alle Zahlen zwischen 2 und getestet wird:

  • Eine Primzahl: 7
 : teilerfremd!
 : teilerfremd!
 : teilerfremd!
 : teilerfremd!
 : teilerfremd!

  • Keine Primzahl: 12
 : nicht teilerfremd!
 : nicht teilerfremd!
 : nicht teilerfremd!
 : teilerfremd!
 : nicht teilerfremd!

In Zusammenhang mit der oben angegebenen Eigenschaft "Eine Primzahl als eine natürliche Zahl größer 1, die nur durch 1 und sich selbst teilbar ist" gibt es noch weitere Eigenschaften, die sich aus dieser Eigenschaft ableiten lassen:

1. Zwei natürliche Zahlen, deren Summe eine Primzahl ergeben, sind immer teilerfremd. Allerdings ergibt die Summe zweier teilerfremder natürlicher Zahlen nicht immer eine Primzahl.

  • Eine Primzahl: 11
 : teilerfremd!
 : teilerfremd!
 : teilerfremd!
 : teilerfremd!

  • Keine Primzahl: 15
 : teilerfremd!
 : nicht teilerfremd!
 : teilerfremd!
 : nicht teilerfremd!
 : nicht teilerfremd!
 : teilerfremd!

2. Es ist nicht möglich, eine Primzahl in die Form eines Rechtecks zu bringen.
Beispiele:

--1--2---3----4---5----6----7----8----9----10-----11----11---
--X--XX--XXX--XX--XXX--XXX-XXXX-XXXX--XXX--XXXXX--XXXX--XXXXX
--------------XX--XX---XXX-XXX--XXXX--XXX--XXXXX--XXXX--XXXXX
--------------------------------------XXX---------XXX---X----

In Kapitel I. Eigenschaften wurde der kleine fermatsche Satz aufgeführt, dass also durch teilbar ist, wenn eine Primzahl ist. Man kann , mit ihrer Eigenschaft, durch die Primzahl teilbar zu sein, immer wieder mal antreffen. Im weiteren wird als dargestellt.

Der kleine Fermat und die allgemeinen Lucas-Folge V(P,Q) = an + bn

[Bearbeiten]

Für alle Lucas-Folgen mit und gilt, dass durch teilbar ist, wenn eine Primzahl ist. Oder anders ausgedrückt:

für alle , die Primzahlen sind.

Es trifft nun zu, dass immer ist. Demzufolge lässt sich auch schreiben: Wenn eine Primzahl ist, dann gilt, dass durch teilbar ist. Das sieht dem kleinen fermatschen Satz ziemlich ähnlich. Und in der Tat ist der Spezialfall: mit identisch mit dem kleinen fermatschen Satz .



Einleitung

[Bearbeiten]

Wir können davon ausgehen, dass Primzahlen existieren, denn sonst würde es dieses Kapitel und das ganze Buch nicht geben. Obwohl ein paar kritische Leser einwerfen, dass dies gar nicht so sicher ist. Wie dem auch sei, wir gehen davon aus, dass es Primzahlen gibt. Um die große Frage, ob es nur endlich viele Primzahlen oder doch unendlich viele Primzahlen gibt, beziehungsweise die Beantwortung dieser Frage geht es in diesem Kapitel. Es gibt also unendlich viele Primzahlen, und die folgenden Beweise handeln davon.

Euklids Beweis

[Bearbeiten]

Der um 300 v. Chr. in Alexandria lebende Mathematiker Euklid hat folgenden Beweis geliefert: Angenommen, es gäbe endlich viele Primzahlen. Dann gäbe es die größte Primzahl . Man kann nun das Produkt aller Primzahlen bilden. ist durch alle Primzahlen von bis teilbar. Die Zahl ist wiederum durch keine der Primzahlen zwischen und teilbar. Daraus folgt, dass entweder eine weitere Primzahl ist, oder das Produkt von noch unbekannten Primzahlen ist. Egal was nun zutreffen mag, es gibt immer mehr Primzahlen als die Primzahlen, die schon bekannt sind.

Beispiele

[Bearbeiten]

Angenommen, 11 sei die größte Primzahl, dann ist aber:

eine Primzahl größer als 11.

Angenommen, 13 sei die größte Primzahl, dann ist aber:

.

zwar selbst keine Primzahl, jedoch das Produkt der Primzahlen 59 und 509, beide größer als 13.


Stieltjes Beweis (1890)

[Bearbeiten]

Angenommen seien die einzigen Primzahlen, die existieren. Dann gilt für die Zahl , dass sie sich in der Form zerlegen lässt, wobei für beide Zahlen und angenommen werden kann, dass sie größer 1 sind und dass jede Primzahl entweder oder teilt, aber nicht beide zugleich. Aus diesem Grund ist durch keine der existierenden Primzahlen teilbar. Da aber ist, ist eine weitere, größere Primzahl oder durch eine weitere noch unbekannte Primzahl teilbar.

Stieltjes Beweis ist im Grunde eine Verallgemeinerung von Euklids Satz, da dieser mit einen Spezialfall von Stieltjes Beweis darstellt.

Beispiel

[Bearbeiten]

Angenommen es gäbe nur die 4 Primzahlen 2, 3, 5 und 7. Dann wäre N = 2 · 3 · 5 · 7 = 210. N ließe sich beispielsweise in die Faktoren 15 (= 3 · 5) und 14 (= 2 · 7) zerlegen. 15 + 14 = 29. Die Zahl 29 lässt sich weder durch 2, 3, 5 oder 7 teilen. Also ist 29 eine Primzahl oder durch wenigstens zwei, zueinander teilerfremde, Primzahlen teilbar, die sich nicht in der Menge {2, 3, 5, 7} befinden.

Schorns Beweis

[Bearbeiten]

Vorbemerkung zu "paarweise teilerfremd"

[Bearbeiten]

Dieser (Schorns) und der folgende (Goldbachs) Beweis erfordern eine Erklärung. Zwei Zahlen a1 und a2 (nicht unbedingt Primzahlen) ohne gemeinsame Primfaktoren, also mit ggT (größter gemeinsame Teiler) 1, heißen teilerfremd. Eine Menge von Zahlen heißt paarweise teilerfremd, wenn je zwei beliebige Zahlen aus dieser Menge teilerfremd sind.

Beweis

[Bearbeiten]

Angenommen, es gäbe genau verschiedene Primzahlen. Dann setze . Die natürlichen Zahlen für sind paarweise teilerfremd. Wenn eine Primzahl die natürliche Zahl teilt, dann sind die Primzahlen unterschiedliche Primzahlen, was im Widerspruch zu unserer anfänglichen Annahme steht, dass es genau verschiedene Primzahlen gibt.

Beispiel

[Bearbeiten]

Angenommen, man geht davon aus, dass es genau 3 Primzahlen gibt. Dann ist . Mit dieser Zahl kann man die folgenden 4 Zahlen konstruieren:

.

Alle vier Zahlen sind also paarweise teilerfremd. Das bedeutet auch, dass es mindestens 4 verschiedene Primzahlen gibt, was der Annahme widerspricht, dass es nur genau 3 Primzahlen gibt.

Vorteil

[Bearbeiten]

Der große Vorteil an Schorns Beweis gegenüber den Beweisen von Euklid und Stieltjes ist, dass man bei ihm nur von einer bestimmten Anzahl von Primzahlen, nicht aber von konkreten Primzahlen ausgeht.

Goldbachs Beweis (1730)

[Bearbeiten]

Wenn man eine unendliche Folge natürlicher Zahlen finden kann, die paarweise teilerfremd sind, dann existiert eine Folge von Primzahlen , für die gilt, dass die Primzahlen die natürliche Zahlen teilen. Diese Primzahlen sind dann alle verschieden. Wenn man also eine solche Folge findet, dann gibt es auch eine unendliche Anzahl von Primzahlen.

Es gibt eine solche Folge natürlicher Zahlen, die paarweise teilerfremd sind: die Folge der Fermat-Zahlen für . Es gilt nämlich . Dieser Satz lässt sich per vollständiger Induktion zeigen. Daraus folgt für , dass die Zahl dividiert. Angenommen eine Primzahl würde die beiden Fermat-Zahlen und dividieren, dann würde sie auch und dividieren. Daraus würde folgen. Da aber jedes ungerade und damit nicht durch 2 teilbar ist, ist jedes Glied dieser Folge teilerfremd zu allen anderen.

Bertrands Postulat

[Bearbeiten]

Bertrands Postulat besagt: Für gilt, daß zwischen und wenigstens eine Primzahl liegt. Nun kann man die unendliche Folge der Natürlichen Zahlen in unendlich viele Abschnitte aufteilen: 2 bis 4; 5 bis 10; 11 bis 22; 23 bis 46; 47 bis 94; 95 bis 190; ... . In jedem dieser unendlich vielen Abschnitte muß wenigstens eine Primzahl liegen. Demzufolge müssen unendlich viele Primzahlen existieren.


Quelle: Die Primzahlbeweise von Thomas Jean Stieltjes, Schorn und Christian Goldbach sind aus dem Artikel Primzahl (Beweise) von der deutsprachigen de.wikipedia.org entnommen. Als ursprüngliche Quelle diente das Buch: The New Book of Prime Number Records, 3. Aufl., Springer Verlag von Paolo Ribenboim.

Die abzählbare Unendlichkeit

[Bearbeiten]

Die Primzahlen bilden eine unendliche Teilmenge der Menge der Natürlichen Zahlen, und sind deshalb abzählbar unendlich.

Einleitung

[Bearbeiten]

Eine Primzahl ist eine natürliche Zahl größer Eins, die nur durch die Eins und sich selbst teilbar ist

[Bearbeiten]

Die naheliegenste Methode zu testen, ob es sich bei einer natürlichen Zahl um eine Primzahl handelt, ist, zu prüfen, ob es eine natürliche Zahl mit gibt, die teilt. Zu prüfen, ob von geteilt wird, ist überflüssig, da und in jedem Fall teilerfremd sind.

Ein Programm dazu:

do forever
  say "Bitte gib eine natürliche Zahl ein (Programm beenden mit 0):"
  pull n
  if (n = 0) then leave
  t = 0
  do i = 2 to n-2
    if ((n // i) = 0) then t = 1
  end
  if (t = 0) then say "Die Zahl "||n||" ist eine Primzahl"
  if (t = 1) then say "Die Zahl "||n||" ist keine Primzahl"
end

Verbesserungsmöglichkeiten des konsequenten Durchtesten

[Bearbeiten]

Man kann das Verfahren des konsequenten Durchtesten auf unterschiedliche Arten verbessern:

  • Wenn aus einem beliebigen Produkt mit der Faktor schon als Teiler getestet wurde, so ist es nicht mehr nötig, Faktor auch noch zu testen.
Angenommen ich teste die Zahl 35 = 5·7 auf ihre primalität. Wenn ich die 5 getestet und festgestellt habe, das sie ein Teiler von 35 ist, kann ich aufhören, weitere Zahlen darauf zu testen, ob sie Faktoren der 35 sind oder nicht. Um mal den Extremfall zu zeigen: Angenommen ich will 49 auf ihre primalität testen. Dann muß ich das nur bis zur 7 machen, weil 7 die Quadratwurzel von 49 ist: 7·7 = 49.
Wie sieht das nun bei einer Primzahl aus? Wie weit muß ich da testen? Bis ? Nein, es reicht, bis zu testen. Warum?
Angenommen, es gibt keinen Teiler kleiner , der teilt. Dann kann es auch keinen Teiler größer geben, der teilt. Warum?
Nehmen wir mal an, wir haben zwei natürliche Zahlen für die gilt teilt und teilt . Daraus würde folgen, das ist. Das ist ein Widerspruch, und deshalb muß man auch nur bis maximal testen.
  • Primzahlen größer 3 haben die Form oder
Aus diesem Grund braucht man Primzahlen, die nicht dieser Form entsprechen nicht kosequent auf alle mögliche Teiler zu testen. Es reicht, einen Vortest auf die Formen und zu machen. Zahlen die nicht diesen Formen entsprechen, fallen als Kandidaten für Primzahlen gleich raus. Das sind aller natürlichen Zahlen.

Ein Programm, das alle Verbesserungen berücksichtigt, könnte so aussehen:

do forever
  say "Bitte gib eine natürliche Zahl ein (Programm beenden mit 0):"
  pull n
  if (n = 0) then leave
  t = 1
  t2 = ((n-1)//6)*((n+1)//6)
  t3 = (n-2)*(n-3)
  if ((n > 3) && (t2 = 0)) then do
    t = 0
    do i = 2 to sqrt(n)
      if ((n // i) = 0) then t = 1
    end
  end
  if (t3 = 0) then t = 0
  if (t = 0) then say "Die Zahl "||n||" ist eine Primzahl"
  if (t = 1) then say "Die Zahl "||n||" ist keine Primzahl"
end

Serie

[Bearbeiten]

Angenommen, man möchte einen ganzen Bereich von 1 bis zu einer bestimmten Oberzahl auf Primzahlen durchsuchen. Dann wäre es nicht sinnvoll, so man das konsequente Durchtesten verwenden würde, immer wieder mit Null anzufangen. Also so ein Programm:


say "Bitte gib eine Obergrenze ein:"
pull n
do i2 = 2 to n
  if (n = 0) then leave
  t = 1
  t2 = ((n-1)//6)*((n+1)//6)
  t3 = (n-2)*(n-3)
  if ((n > 3) && (t2 = 0)) then do
    t = 0
    do i = 2 to sqrt(n)
      if ((n // i) = 0) then t = 1
    end
  end
  if (t3 = 0) then t = 0
  if (t = 0) then say n
end
pull x

wäre nicht sinnvoll. Besser ist es, schon gefundene Primzahlen im Programm zu speichern:


Wenn man testen möchte, ob eine natürliche Zahl eine Primzahl ist, kommt einem vielleicht als erstes das Konsequente Durchtesten auf Teilbarkeit in den Sinn. Dabei testet man, ob es eine natürliche Zahl zwischen 2 und gibt, die teilt. Existiert keine natürliche Zahl zwischen 2 und gibt, die teilt, so ist eine Primzahl. Findet sich wenigstens eine Zahl zwischen 2 und die teilt, so ist keine Primzahl.

Das Sieb des Eratosthenes

[Bearbeiten]

Das Sieb des Eratosthenes ist ein altes Verfahren, um alle Primzahlen zwischen 2 und einer fest vorgebenen Obergrenze aus den natürlichen Zahlen herauszufiltern. Dabei speichert man alle Zahlen zwischen 2 und Obergrenze in ein Array und markiert sie als Primzahlen. Dann beginnt das Sieben: Die kleinste Zahl, die als Primzahl markiert ist wird herausgesucht (das ist zu Anfang die 2), nun werden alle Vielfachen der Primzahl, beginnend mit dem Quadrat der Primzahl als Nichtprimzahlen markiert. Nach diesem Durchlauf, wird die nächstgrößere Zahl herausgesucht, die als Primzahl markiert ist. Das Ganze läuft solange ab, bis die nächste Zahl größer als ist. Alle Zahlen, die jetzt noch als Primzahlen markiert sind, sind auch Primzahlen.

obergrenze=10000
/* Initialisierung des Primzahlfeldes: Alle Zahlen größer gleich 2 */
/* sind Primzahlen                                                 */
do i=2 to obergrenze
  primzahlfeld.i=1
end
/* Der Siebprozess beginnt hier */
do i=2 to sqrt(obergrenze)
  if (primzahlfeld.i=1) then
  do i2=i*i to n by i
    primzahlfeld.i2=0
  end
end
/* Hier werden die Primzahlen ausgegeben */
do i=2 to n
  if (primzahlfeld.i=1) then say i;", "; 
end

Primfaktorzerlegung

Einleitung

[Bearbeiten]

Angenommen, man hat eine Zahl vor sich, z.B. 7657 und möchte nun die Teiler dieser Zahl bestimmen. Mal vorausgesetzt, es handelt sich um keine Primzahl, kann man anfangen, die Zahl auf einzelne Teiler zu testen:

Die letzte Ziffer ist 7, also ist sie weder durch 2 noch durch 5 teilbar. Die Quersumme ist 25, die nicht durch 3 teilbar ist, und damit ist 7657 auch nicht durch 3 teilbar.
Durch 7 dividiert ergibt 7657 als Ergebnis 1093 Rest 6. Folglich ist 7657 auch nicht durch 7 teilbar. Machen wir es kurz: 7657 ist auch nicht durch 11, 17, 23 und 29 teilbar. Die Primfaktorzerlegung von 7657 ist 13·19·31.

Um die Primfaktorzerlegung zu Automatisieren, kann man nun, rein theoretisch, die Teilbarkeit durch eine Liste von Primzahlen testen, die in dem Programm fest vorgegeben ist. Das hat zwei Nachteile:

  1. Das Programm wird dadurch ziemlich groß.
  2. Es besteht immer die Möglichkeit, dass die Zahl, zu der die Primfaktorzerlegung durchgeführt werden soll, Primfaktoren enthält, die in dem Programm nicht vorhanden sind.

Die Mutter aller Faktorisierungsverfahren

[Bearbeiten]

Es gibt ein Verfahren, mit dem man diese Probleme umgehen kann. Dieses Verfahren heißt nach dem französischen Amateurmathematiker Pierre de Fermat die Primfaktorzerlegung nach Fermat. Aber zuerst ein paar Überlegungen:

Eine zusammengesetzte, ungerade natürliche Zahl läßt sich als Produkt zweier ungerade natürlicher Zahlen und darstellen:
Man kann, unter der Bedingung , zwei natürliche Zahlen und mit finden, so dass und gilt, nämlich als Lösung eines linearen Gleichungssystems mit den Variablen und . Über die dritte binomische Formel kommt man zu der Gleichung :
Man kann also auch als Differenz zweier Quadrate ansehen Das ist die Grundlage für die Primfaktorzerlegung nach Fermat: Wenn man eine Quadratzahl findet, so dass für auch ein Quadrat ist so kann man zwei Teiler bestimmen.

Bei dem Fermatschen Verfahren sind ein paar Dinge zu beachten:

  1. Das fermatsche Verfahren kann nur ungerade Zahlen faktorisieren. Zweierpotenzen sind also vor der Primfaktorisierung zu entfernen.
  2. Das fermatsche Verfahren kann Quadrate nicht von Primzahlen unterscheiden (dazu später mehr).

Der Bereich des Fermatschen Verfahren läßt sich eingrenzen:

Man beginnt bei dem kleinsten mit Die obere Grenze liegt bei so dass ist.

Die Effizienz des Faktorisierungsverfahren nach Fermat hängt vom Aufbau der zu testenden Zahl ab. Es folgen ein ideales und ein negatives Beispiel.

Das ideale Beispiel

[Bearbeiten]

Zu faktorisieren ist die Zahl 19043. Die untere Grenze liegt bei und die obere Grenze bei Schon bei

findet man ein Quadrat, was die Zerlegung

liefert.

Wie man sehen kann, liegt der kleinste positive Treffer mit bei der unteren Grenze. Und nicht nur das, er liefert auch gleich die vollständige Primfaktorzerlegung 19043 = 137·139 zurück. Dass dies so ist, liegt daran, dass die Zahl nur aus zwei Primfaktoren besteht und außerdem die beiden Primfaktoren dicht beieinander liegen.

Die obere Grenze führt noch zu:

was die Zerlegung

liefert.

So ein Fall kommt eher selten vor; deshalb folgt noch das Negativbeispiel.

Das negative Beispiel

[Bearbeiten]

Zu faktorisieren ist die Zahl 12341. Die untere Grenze liegt bei und die obere Grenze bei

ist kein Quadrat,
ist kein Quadrat,

und so weiter. Erst bei

findet man ein Quadrat, was die Zerlegung

liefert.

Die weiteren Prüfungen liefern (nur) für die Zahlen 171, 885 und 6171 Treffer. Diese Zahlen führen zu folgenden Zerlegungen:

Erst bei liefert die Gleichung den ersten positiven Treffer. Das bedeutet, es müssen 53 Quadratzahlen getestet werden, bis der erste Treffer gefunden wird. Demgegenüber findet man beim Divisionsverfahren schon mit der vierten Primzahl (der 7) einen Teiler. Noch schlechter ist, dass 12341 = 287·43 nicht die komplette Primfaktorisierung zurückliefert.

Man braucht alle drei Treffer, um alle Primfaktoren zu ermitteln, und erst ein Kreuzvergleich über den größten gemeinsamen Teiler mit allen Teilergebnissen bringt Sicherheit.

Einleitung

[Bearbeiten]

Es sind häufig zwei Fragen, die sich in Bezug auf die Primzahlen stellen:

  1. Ist die vorliegende Zahl eine Primzahl?
  2. Wie läßt sich die vorliegende Zahl zerlegen?

Ist die vorliegende Zahl eine Primzahl?

[Bearbeiten]

Wenn die vorliegende Zahl sehr klein ist, also kleiner als 90, dann kann man schon mit etwas Überlegung sagen, ob es sich um eine Primzahl handelt, oder nicht. Die 91 ist der erste kleine Stolperstein, da sie die erste Zahl ist, deren sämtliche Primfaktoren größer als fünf sind (91=7·13). Wer allerdings Primzahlen auswendig weiß, kann durchaus bis 127 und höher kommen. Aber wer lernt schon vier- oder mehrstellige Primzahlen auswendig (333667 mag da, z.B. wegen ihrer Eigenschaften, eine Ausnahme sein). Also braucht man ein Verfahren, um solche Zahlen auf ihre Primalität zu testen.

Probabilistische Verfahren

[Bearbeiten]
  • Fermat
  • Solovay-Strassen
  • Miller-Rabin

Sonderfall Sieb des Eratosthenes

[Bearbeiten]

Das Sieb des Eratosthenes ist ein Sonderfall. Im Gegensatz zu Verfahren, die einzelne Zahlen auf ihre Primalität prüfen, siebt das Siebverfahren aus einem vorgegebenen Zahlenbereich, von 2 bis zu einer vorgegebenen Obergrenze, alle Nichtprimzahlen aus, so dass nur die Primzahlen übrig bleiben. Dabei wird wie folgt vorgegangen. Jede natürliche Zahl zwischen 2 und der Obergrenze bekommt eine Art kleines Schild, auf der ihr Zustand bezüglich der Primalität geschrieben steht. Am Anfang werden alle Zahlen zwischen 2 und Obergrenze als Primzahl deklariert. Nun wird die erste Zahl genommen, das ist die 2, und nachgesehen, ob es eine Primzahl ist. Die 2 hat die Information Primzahl. Wenn also die 2 eine Primzahl ist, dann können alle Vielfachen von 2, angefangen mit 22 keine Primzahlen mehr sein. Dementsprechend wird auf allen Schildern der Vielfachen von 2, angefangen mit 22 bis Obergrenze, die Information von Primzahl auf Nichtprimzahl geändert. danach wird die nächste Zahl, das ist die 3, auf ihre Primalität getestet. Wieder werden, im Falle, dass es sich um eine Primzahl handelt alle Vielfachen in ihrem Zustand von Primzahl auf Nichtprimzahl geändert. Das Ganze wird solange gemacht, bis man die Quadratwurzel von Obergrenze erreicht hat, weswegen es sinnvoll ist, als Obergrenze eine Quadratzahl einzusetzen. Wenn man z.B. ein Zahlenfeld von 2 bis 10.000 siebt, dann muß man nur bis 100 testen, da 1002 = 10.000 ist. Alle Zahlen größer 100, die noch auf ihrem Schild Primzahl stehen haben, sind auch Primzahlen.

Der Sinn des Sieb des Eratosthenes ist, Primzahltabellen zu erstellen, in denen man - bei kleineren Zahlen - nachsehen kann, ob es sich bei der gesuchten Zahl um eine Primzahl handelt. Im Anhang findet man mit Primzahlen: Tabelle der Primzahlen (2 - 100.000) eine Primzahltabelle (bzw. einen Teil einer Primzahltabelle), die mit einem Programm, das den Algorithmus Sieb des Eratosthenes benutzt, generiert worden ist.

Wie ist die Primfaktorzerlegung?

[Bearbeiten]

Einleitung

[Bearbeiten]

In diesem Kapitel geht es um die Verteilung der Primzahlen

Die abzählbare Unendlichkeit

[Bearbeiten]

Wie im II. Kapitel: Die Unendlichkeit der Primzahlen gezeigt, bilden die Primzahlen eine abzählbar unendliche Teilmenge der Natürlichen Zahlen. Die Menge der Primzahlen lässt sich also abzählen:

Eine mögliche Zuordnung wäre:

Die Primzahl-Funktion

[Bearbeiten]

Die Funktion gibt die Anzahl aller Primzahlen bis zu einer vorgegebenen Grenze an. So gibt es unter 100 25 Primzahlen, und demzufolge ist . Aber wie lässt sich berechnen?

Mindestens so: falls keine Primzahl ist und falls Primzahl

  • Beispiel
n π(n)
10 4
100 25
1000 168
10.000 1229
100.000 9592
1.000.000 78498

Der Primzahlsatz

[Bearbeiten]

Der Primzahlsatz besagt, wie sich die Primzahl-Funktion asymptotisch verhält. Es zeigt sich, dass sich asymptotisch verhält wie die Funktion , d. h. die Funktionen und sind asymptotisch äquivalent. Formel:

Eine noch bessere Approximation als ist der Integrallogarithmus

Die Ableitung des Integrallogarithmus ist eine Näherung für die Wahrscheinlichkeit, dass eine ganze Zahl eine Primzahl ist:

und
für ungerade Zahlen .


Einleitung

[Bearbeiten]

In diesem Kapitel geht es um die Lücken zwischen zwei Primzahlen und deren Größe.

Primzahllücken

[Bearbeiten]

Was versteht man unter einer Primzahllücke? Das ist ganz einfach. Eine Primzahllücke ist der Abstand zwischen zwei aufeinanderfolgenden Primzahlen. Als Länge der Primzahllücke bezeichnet man die Differenz zweier aufeinanderfolgender Primzahlen. Die bekannteste Form der Primzahllücken sind die Primzahlzwillinge, zwei Primzahlen und , zwischen denen genau eine Nichtprimzahl liegt.

Gibt es die Möglichkeit, Primzahllücken einer bestimmten Mindestlänge zu konstruieren?

[Bearbeiten]

Ja, die Möglichkeit gibt es. Hier werden drei Vorgehensweisen vorgestellt:

Konstruktion einer Primzahllücke über die Fakultät:

[Bearbeiten]

Die Fakultät hat die folgende Eigenschaft, dass sie durch alle Zahlen von 2 bis n teilbar ist. Demzufolge ist eine Zahl mit auch durch teilbar, und damit keine Primzahl. Auf diese Weise bekommt man eine feste Lücke aus Nichtprimzahlen zwischen und .

Beispiel:

[Bearbeiten]

n=6

ist durch 2 teilbar.
ist durch 3 teilbar.
ist durch 4 teilbar.
ist durch 5 teilbar.
ist durch 6 teilbar.

Konstruktion einer Primzahllücke über das kgV

[Bearbeiten]

Das folgende Verfahren ist mit der Konstruktion über die Fakultät verwandt. Das ist, wie die Fakultät , durch alle Zahlen zwischen 2 und n teilbar. Wie bei dem Verfahren mit der Fakultät gilt, dass das mit durch teilbar ist, und damit keine Primzahl sein kann. Und genauso wie bei dem Verfahren mit der Fakultät bekommt man eine feste Lücke aus Nichtprimzahlen zwischen und .

Beispiel:

[Bearbeiten]

n=6

ist durch 2 teilbar.
ist durch 3 teilbar.
ist durch 4 teilbar.
ist durch 5 teilbar.
ist durch 6 teilbar.

Konstruktion einer Primzahllücke über das Primorial

[Bearbeiten]

Dieses Verfahren ist etwas subtiler. Es beruht auf einer mathematischen Operation, die im englischen primorial genannt wird. Das primorial ist das Produkt aller Primzahlen zwischen 2 und . Hierbei ist nicht sichergestellt, dass alle natürlichen Zahlen zwischen 2 und als Teiler vorhanden sind. Aber dies ist auch gar nicht nötig, denn alle Zahlen zwischen 2 und können nur Primzahlen zwischen 2 und als Faktoren enthalten.

Beispiel:

[Bearbeiten]

n=5 (bis , da erst 7 die nächst höhere Primzahl ist)

ist durch 2 teilbar.
ist durch 3 teilbar.
ist durch 2 teilbar.
ist durch 5 teilbar.
ist durch 6 teilbar.

Einschränkung

[Bearbeiten]

Keines der genannten Verfahren garantiert, dass die direkt an die Lücke grenzenden Zahlen Primzahlen sind. Die eigentliche Lücke kann in Wirklichkeit wesentlich größer sein:

Beispiele:

[Bearbeiten]

n=8

ist durch 2 teilbar.
ist durch 3 teilbar.
ist durch 4 teilbar.
ist durch 5 teilbar.
ist durch 6 teilbar.
ist durch 7 teilbar.
ist durch 8 teilbar.

Die nächsten Primzahlen sind allerdings erst 40289 und 40343, und damit liegen 53 statt nur 7 Nichtprimzahlen in der Lücke.

n=11

ist durch 2 teilbar.
ist durch 3 teilbar.
ist durch 4 teilbar.
ist durch 5 teilbar.
ist durch 6 teilbar.
ist durch 7 teilbar.
ist durch 8 teilbar.
ist durch 9 teilbar.
ist durch 10 teilbar.
ist durch 11 teilbar.

Die nächsten Primzahlen sind allerdings erst 27701 und 27733, und damit liegen 31 statt nur 10 Nichtprimzahlen in der Lücke.

n=11

ist durch 2 teilbar.
ist durch 3 teilbar.
ist durch 2 teilbar.
ist durch 5 teilbar.
ist durch 6 teilbar.
ist durch 7 teilbar.
ist durch 2 teilbar.
ist durch 3 teilbar.
ist durch 10 teilbar.
ist durch 11 teilbar.

Die nächsten Primzahlen sind allerdings erst 2311 und 2333, und damit liegen 21 statt nur 10 Nichtprimzahlen in der Lücke.

  • Primzahlen: VI. Kapitel: Verschiedene Primzahl-Arten
  • Primzahlen: VII. Kapitel: Primzahlgeneratoren

Einleitung

[Bearbeiten]

Die Sache, um die es hier geht, ist mit der Fakultät verwandt, also mit dem Produkt aller natürlichen Zahlen zwischen 1 und n:

Das Produkt aller Primzahlen bis zu einer vorgegebenen Grenze wird mit ausgedrückt, wobei es zwei verschiedene Lesarten gibt:

Definition 1:

ist eine Primzahl, und ist das Produkt der Primzahlen von bis .
Beispiel:

Definition 2:

ist das Produkt der ersten Primzahlen.
Beispiel:

Wenn in diesem Buch von die Rede ist, dann bezieht sich das auf die erste Definition.

Eine andere Sache ist die Benennung dieser Operation. Im englischen Sprachraum etabliert sich die Bezeichnung primorial (Verschmelzung von prime für Primzahl und factorial für Fakultät), im Deutschen müsste es logischerweise Primultät (Verschmelzung von Primzahl und Fakultät) heißen. Die Ausdrücke Primzahlfakultät und Primfakultät sind Kompromisse.

Welche Bezeichnung sich in Zukunft im deutschen Sprachraum durchsetzen wird, wird die Zukunft zeigen. Und da ja auch wenigstens zwei Definitionen für die Operation existieren, wird man bei der Verwendung von immer angeben müssen, auf welche Definition sie sich bezieht.

Anhänge

[Bearbeiten]
  • Primzahlen: zeitliche Abfolge

Eratosthenes von Kyrene (auch Erathostenes genannt) (* ca. 284 v. Chr. in Kyrene; † 202 v. Chr. in Alexandria war ein griechischer Mathematiker sowie Direktor der Bibliothek von Alexandria. Nach Eratosthenes ist das Sieb des Eratosthenes benannt, einem Verfahren, mit dem man aus einem endlichen Zahlenfeld die Primzahlen heraussieben kann. Auf diese Weise lassen sich Primzahltabellen erstellen.

Euklid war ein griechischer Mathematiker der ca. 300 v. Chr. in Alexandria lebte. Auf Euklid geht der Satz von Euklid zurück, dem ersten bekannten Beweis, dass keine größte Primzahl existiert, und damit unendlich viele Primzahlen existieren.

(* 15. April 1707 in Riehen (Schweiz), † 18. September 1783 in St. Petersburg)

Pierre de Fermat (* Ende 1607 oder Anfang 1608 in Beaumont-de-Lomagne, † 12. Januar 1665 in Castres) war ein französischer Jurist und Amateurmathematiker. Seine besonderen Leistungen liegen im kleinen fermatschen Satz und dem großen fermatschen Satz - der Behauptung, dass es für keine ganzzahlige Lösung mit gibt. Diese Vermutung wurde erst Ende des 20. Jahrhunderts, also nach mehr als 300 Jahren bewiesen.

Pierre de Fermat vermutete, dass alle Zahlen der Form Primzahlen sind. Diese Vermutung wurde 1732 von Leonhard Euler widerlegt. Nach Fermat heißt diese Art von Zahl Fermat-Zahl; mit sind diese Zahlen tatsächlich Primzahlen und werden Fermatsche Primzahlen genannt. Der deutsche Mathematiker Christian Goldbach hat die Fermat-Zahl für einen Beweis, dass es unendlich viele Primzahlen geben muss, verwendet.

Primzahlsatz

[Bearbeiten]

Anzahl der Primzahlen kleiner gleich :

mit

Eine noch bessere Approximation als ist der Integrallogarithmus

Wahrscheinlichkeit, dass eine ganze Zahl eine Primzahl ist:

Binomialkoeffizient

[Bearbeiten]

Der Binomialkoeffizient kommt aus der Wahrscheinlichkeitsrechnung. Mit Hilfe des Binomialkoeffizienten lässt sich berechnen, wieviele Möglichkeiten es gibt m Objekte aus einer Gesamtzahl von n unterschiedlchen Objekten auszuwählen. Berechnet wird der Binomialkoeffizient nach der Formel:

Beispiele

[Bearbeiten]

Man hat in einem Beutel sechs farbige Kugeln (rot, grün, blau, gelb, magenta, cyan). Wieviele unterschiedliche Kombinationen zweier Kugeln lassen sich aus dem Beutel nehmen?

Es gibt 15 Kombinationen.

Das bekannteste Beispiel für einen Binomialkoeffizienten ist das Lotto 6 aus 49. Wieviele Kombinationen von 6 Zahlen kann man aus 49 Zahlen zusammenstellen?

Es sind 13.983.816 (das sind fast 14 Millionen).

Sieb des Eratosthenes

[Bearbeiten]

Die Spezifikation des Algorithmus in Pseudocode ist in der Wikipedia zu finden.

Prinzip

[Bearbeiten]

Das Sieb des Eratosthenes ist ein Verfahren, um alle natürlichen Zahlen (ferner nur mit „Zahlen“ bezeichnet) bis zu einer vorgegebenen Zahl n, einschließlich n selbst, auf Primalität zu testen (zu Primzahlen siehe auch die Seite Primfaktorisierung) und, sofern sie prim sind, auszugeben. Das Sieb des Eratosthenes "zäumt das Pferd von hinten auf": Es werden alle Zahlen bis n (inklusive) größer als 1 hintereinander aufgeschrieben. Dann werden die Zahlen der Reihe nach durchgegangen. Die echten Vielfachen der aktuellen Zahl (für 3 z. B. 6, 9, 12, ...) werden durchgestrichen. Übrig bleiben die Zahlen , die keine echten Vielfachen einer Zahl echt zwischen 1 und sind. Dies sind sämtliche Primzahlen bis zur vorgegebenen Grenze.

Beispiel

[Bearbeiten]

Sei . Hintereinander werden die Zahlen 2, 3, 4, 5, 6, 7, 8, 9, 10 aufgeschrieben. Die 2 wird betrachtet und ihre echten Vielfachen weggestrichen: 2, 3, 4, 5, 6, 7, 8, 9, 10. Dasselbe für die 3: 2, 3, 4, 5, 6, 7, 8, 9, 10. Übrig sind noch 2, 3, 5 und 7. Dies sind, wie wir überprüfen können, alle Primzahlen im betrachteten Intervall, sodass hier abgebrochen werden kann. Schritte, um das Verfahren zu optimieren, damit der Algorithmus wirklich schon so früh endet, werden im nächsten Absatz besprochen.

Optimierungen eines simplen Durchgehens aller Zahlen und ihrer echten Vielfachen

[Bearbeiten]

Es müssen nur die Zahlen bis einschließlich betrachtet werden, wobei den ganzzahligen Anteil (die Abrundungsfunktion) symbolisiert. Denn sei , dann gilt für die Vielfachen: , alle Vielfachen von wurden also bereits als Vielfache von gestrichen.

Bereits gestrichene Zahlen müssen nicht mehr betrachtet werden, da ihre echten Vielfachen garantiert durch einen echten Teiler der gestrichenen Zahl teilbar sind.

Weiter optimieren kann man unter anderem, indem man das Wegstreichen der echten Vielfachen einer Zahl erst bei beginnt. Denn alle Vielfachen sind von der Form mit . Damit wurden sie aber als ganzzahlige Vielfachen einer kleineren Zahl schon überprüft.

Komplexitätstheoretische Beschreibung

[Bearbeiten]

Durch diese und weitere Optimierungen lässt sich die Laufzeit auf reduzieren. Beim Vergleich verschiedener Implementierungen und Varianten des Algorithmus ist die Ordnung der Laufzeit aber nur bedingt von Nutzen, da sie Konstanten außer Acht lässt. Bei diesem speziellen Problem wird der Sachverhalt bei einem Vergleich verschiedener Varianten auch bei großen n offensichtlich.

Die Speicherplatzkomplexität lässt sich auf drücken.

Haskell

[Bearbeiten]

Ein einfaches Primzahlsieb in der Programmiersprache Haskell implementiert. Der Speicherbedarf des Algorithmus ist in Bits, wobei die Anzahl der auszugebenen Primzahlen und die größte auszugebene Primzahl bezeichnet.

> module Sieve
> where 

> sieb :: [Int] -> [Int]
> sieb (l:ls) = l:sieb[x | x <- ls, mod x l /= 0]

> take_primes n = take n $ sieb [2..]

Ausführen via

# hugs Sieve
oder für eine schnellere Version
# ghc -O2 --make Sieve.lhs
# ghci Sieve

Im Haskell-Interpeter zur Ausgabe der beispielsweise ersten 100 Primzahlen:

Prelude Sieve> take_primes 100

Siehe hierzu Gambas:_Rechnen#Primzahlen_berechnen

Visual Basic 3

[Bearbeiten]

Dieses Programm liefert die Primzahlen von 1 bis 2100000000

Hinter dem Befehl Berechnen steht der unten folgende Code. Der Code wurde mit vielen Rem Kommentaren versehen. Sie können die rem Kommentare herauswerfen und wahrscheinlich auch die Variable j streichen. Versuchen Sie den Fehler bei der Print Ausgabe mit der Startzahl 1-5 zu eliminieren.

 Sub Befehl1_Click () 
 Cls 
 j = 1 
  Rem Zähler j für die ungeraden Zahlen die keine Primzahlen sind 
  Rem ist wahrscheinlich überflüssig 
  m = text1.Text 
   Rem holt sich aus dem Textfeld1 die erste Zahl zum Testen 
  If m / 2 = Int(m / 2) Then m = m - 1 
    Rem Falls diese Zahl ohne Rest durch 2 teilbar ist, also eine gerade Zahl ist 
    Rem geht das Programm noch eine Zahl rückwärts um eine ungerade Zahl zu bekommen 
  If text1.Text = "" Then m = 6 
    Rem Falls keine Startzahl eingegeben wurde wird die Startzahl m = 6 vergeben. 
  For m = m To m + 1000 Step 2 
   Rem Hauptschleife 
   Rem Die nächsten 1000 ungeraden Zahlen in einer Schleife durchlaufen lassen 
   Rem m ist die Variable für die ungeraden Zahlen 
   f = 1 
   Rem f ist die Variable für die Faktorentestung, 
   Rem m teilbar durch f oder nicht 
   n = m 
   Rem n = ist die Testzahl, bei der noch nicht klar ist ob sie eine Primzahl ist 
   Do While f < Sqr(n) 
    Rem solange der Teiler f kleiner als die Wurzel 
    Rem aus der Testzahl n ist, muß getestet werden 
    f = f + 2 
    Rem Teiler von f = 1 beginnend um jeweils 2 vermehren , 3,5,7,9 etc erster Test also mit f = 3 
    Do While n / f = Int(n / f) 
     Rem Teiler f testen solange bis n / f ohne Rest teilbar 
     Rem Print "m = "; m; " n = "; n; " f = "; f; "j = "; j 
     Rem Wenn Sie bei der letzten Zeile das Rem herauswerfen , 
     Rem erkennen Sie die Bedeutung der Variablen 
     j = j + 1 
     Rem j ist ein Zähler für die ungeraden Zahlen die keine Primzahlen sind 
     Rem j ist wahrscheinlich überflüssig 
     n = Int(n / f) 
     Rem Die Testzahl n verkleinern auf die Zahl n/f 
    Loop 
   Loop 
   A$ = " 1" + Chr(13) + " 2" + Chr(13) + " 3" 
   If m < 7 Then Print A$ 
   Rem Chr(13) = Zeilenwechsel 
   Rem Am Anfang zwischen 1 und 5 gibt es Probleme mit der Ausgabe 
   Rem deswegen werden die ersten drei Zeilen ersetzt durch A$ 
  If n = m Then b = b + 1: Print n: text1.Text = n 
  Rem Wenn die Testzahl n nicht teilbar war durch f 
  Rem ist es eine Primzahl und kann ausgedruckt werden 
  If b = 30 Then m = m + 1000  
  Rem b ist die Zeilennummer, 
  Rem bis Zeile b = 30 werden die berechneten Primzahlen ausgegeben 
  Rem bei Zeile 30 wird die Schleife abgebrochen, 
  Rem da m größer als m + 1000 gesetzt wird 
  Rem wenn ihr Bildschirm die Zahlen nicht mehr komplett anzeigt 
  Rem können Sie für b einen anderen Wert als 30 nehmen 
 Next m 
 Rem Hauptschleife durchlaufen , 
 rem wieder Start am Beginn der Hauptschleife 
 End Sub

Möglichkeit 1

[Bearbeiten]

Hier ein möglicher Quelltext eines Java-Programms zur Ausgabe der Primzahlen von 1-100 (Der Bereich kann natürlich beliebig erweitert werden). Die Primzahlen werden dann in der Konsole ausgegeben.

public class Primzahlen {

    public static void main(String[] args) {
        int limit = 100;
        int zahl;      // Zu überprüfende Zahl
        int zaehler;   // Hilfsvariable (möglicher Teiler von zahl)
        boolean primzahl; // Hilfsvariable, ob die aktuelle Zahl eine Primzahl ist

        // zahl <= x   ist der zu überprüfende Zahlenraum
        // Beginn bei 2, weil 1 per Definition keine Primzahl ist
        for (zahl = 2; zahl <= limit; zahl++) {
            // solange wir für zahl keinen Teiler finden, gehen wir davon aus,
            // dass es eine Primzahl ist
            primzahl = true;

            // zaehler ist ein möglicher Teiler. Mögliche nicht-triviale Teiler
            // liegen im Bereich 2 bis zahl/2 (abgerundet), wenn x aber Teiler
            // von Zahl und größer als Wurzel(zahl), ist zahl/x < Wurzel(zahl), 
            // sodass diese Grenze genügt.
            for (zaehler = 2; zaehler < Math.sqrt(zahl) + 1; zaehler++) {
                if (zahl % zaehler == 0) {
                    // zaehler ist ein nichttrivialer Teiler von zahl und damit
                    // zahl keine Primzahl. Weitere Teiler müssen nicht geprüft
                    // werden und damit kann die Schleife abgebrochen werden.
                    primzahl = false;
                    break;
                }


            }

            if (primzahl) {
                // Keine Teiler gefunden -> zahl2 ist eine Primzahl
                System.out.println(zahl+" ist eine Primzahl");
            }
        }
    }
}

Möglichkeit 2

[Bearbeiten]

Dies ist eine lauffähige Implementierung der brute-force-Version des Siebes von Eratosthenes mit leichten Optimierungen. Die main()-Funktion lässt sich z. B. zum Testen nutzen. Zuerst wird eine Liste erzeugt, die Map-Einträge enthält, welche eine Zahl und ihren Status (durchgestrichen?) repräsentieren.
Zur Erzeugung eines einzelnen Map-Eintrages brauchte ich das Objekt java.util.AbstractMap.SimpleEntry<K, V>, da Map.Entry als Interface keinen Konstruktor besitzt. Dies ist die eleganteste und schnellste Lösung, ansonsten hätte ich ein komplettes Set mit den Werten erzeugen, dessen Einträge durch Iteration über Set.entrySet() an eine Liste anhängen und diese dann sortieren müssen (bestmögliche Komplexität einer vergleichsbasierten Sortierung: ), da selbst bei Maps, die SortedMap implementieren, entrySet() nicht zwingend sortiert ist.
Nach Abschluss der Durchstreich-Phase werden die noch nicht durchgestrichenen Zahlen in eine Liste geschrieben und als Ergebnis zurückgegeben.

// Benötigt Java 8!

import java.util.*;

public class Primzahlgenerator {

    public static void main(String[] args){

    }

    public static List<Integer> siebDesErasthotenes(int obereGrenze){
        // Prüft sämtliche ganzen Zahlen echt zwischen 1 und der oberen Grenze sowie die obere Grenze selber auf Primalität
        List<AbstractMap.SimpleEntry<Integer, String>> kandidaten = new ArrayList<>();

        List<Integer> ergebnis = new ArrayList<Integer>();

        String gestrichen = "gestrichen";
        String unberuehrt = "unberührt";

        for(int i = 2; i <= obereGrenze; i++){
            kandidaten.add(new AbstractMap.SimpleEntry<>(i, unberuehrt));
        }
       
        int element;
        int index;

        for (int i = 0; i < kandidaten.size() / 2 + 1; i++){
            if (!(kandidaten.get(i).getValue().equals(gestrichen))) {
                element = kandidaten.get(i).getKey();
                index = 2 * element - 2; // Index des nächsten Vorkommens
                while (index < kandidaten.size()) {
                    (kandidaten.get(index)).setValue(gestrichen);  // ArrayList.get in O(1)!
                }
            }
        }
        
        for (Map.Entry<Integer, String> eintrag: kandidaten){
            if (eintrag.getValue() == unberuehrt) {
                ergebnis.add(eintrag.getKey());
            }
        }
        
        return ergebnis;
    }
}

Folgende eigenständig lauffähige Konsolenanwendung (.NET 2.0) gibt alle Primzahlen bis n nach dem Sieb des Eratosthenes aus:

using System;
using System.Collections.Generic;
using System.Text;

namespace eratosthenes
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = 100;
            bool[] prime = new bool[n];
            //Zuerst alle Zahlen von 2 bis n als Primzahl markieren
            for (int i = 2; i < n; i++)
            {
                prime[i] = true;
            }

            //Einzelner Abschnitt
            {
                //Wir wollen bei 2 anfangen
                int i = 2;

                //Alle Produkte des Teilers i
                //angefangen bei 2, bis kleiner n durchlaufen
                //Wenn n = 50, dann ist bei i = 7 Schluss, weil das Produkt = 49 ist
                for (; i * i < n; i++)
                {
                    //Wenn die Zahl im Array als Primzahl markiert ist
                    //Was bei den ersten beiden 2 und 3 definitiv der Fall ist
                    if (prime[i])
                    {
                        //Primzahl bis Wurzel(n) ausgeben
                        Console.WriteLine(i);
                        //Alle weiteren Produkte des Teilers i
                        //angefangen beim Produkt i * i bis kleiner n durchlaufen
                        //j wird mit i beim nächsten Durchlauf (Vielfaches) addiert
                        for (int j = i * i; j < n; j += i)
                        {
                            //Dies kann unmöglich eine Primzahl sein
                            //weil es ein Vielfaches von i ist.
                            prime[j] = false;
                        }
                    }
                }

                //Alle Primzahlen ausgeben
                for (; i < n; i++)
                {
                    if (prime[i])
                    {
                        Console.WriteLine(i);
                    }
                }
            }
            
            Console.ReadLine();
        }
    }
}

Delphi

[Bearbeiten]

Folgende Konsolenanwendung gibt mit Hilfe der Funktion isPrim() von einer bestimmten Zahlenmenge die Primzahlen aus.

program Primzahl;

{$APPTYPE CONSOLE}

uses
  SysUtils;

function IsPrim(AInteger: Integer): boolean;
var
  i: Integer;
begin
  result := true;
  if (AInteger <= 1) then  //Wenn Zahl kleiner ist als 2: keine Primzahl
    begin
      result := false;
      exit;               //Funktion beenden
    end;
  for i := 2 to Round(Sqrt(AInteger)) do //Wenn eine Zahl n von 2 bis Wurzel(n)
    begin                                // nicht teilbar ist, ist sie eine Primzahl
      if AInteger mod i = 0 then         //mod: Modulo = Rest
        begin
          result := false;
          exit;
        end;
    end;
end;

var
  a, b: Integer;
  i: Integer;
begin
  Write('von: ');
  Readln(a);       //a abfragen
  Write('bis: ');
  Readln(b);       //b abfragen
  for i := a to b do
      if IsPrim (i) then Writeln(i);    //wenn i eine Primzahl ist: i ausgeben
  Readln;
end.

Python

[Bearbeiten]

Theoretisch ein endloser Primzahl-Generator – nur durch die Hardware begrenzt –, aber langsamer als Siebe. Er nutzt den Satz von Wilson in umgestellter Form. Der Programmlauf wird durch Strg-C gestoppt.

#!/usr/bin/python
# -*- coding: utf-8 -*-

import sys, time

def pgen():
  ''' ... generates the sequence of all primes: 2,3,5,7,11 ... 
  '''

  p=2
  f=1

  try:

    ts2=time.time()

    while(True):

      if f%p%2: sys.stdout.write(str(p)+"\n")
      p+=1
      f*=(p-2)

  except:

#   raise KeyboardInterrupt .. Ctrl-C

    ts2-=time.time()
    sys.stderr.write("time: "+str(round(-ts2,3))+" sec\n")

def main():
  pgen()
  sys.exit()

if __name__=="__main__":
  main()

Python 2

[Bearbeiten]

Dieses Script bittet den Benutzer zuerst nach einer Obergrenze und gibt danach alle Primzahlen bis zu dieser Grenze aus.

#!/usr/bin/env python
# -*- coding: utf-8 -*-

def main():
    
    # Frage den Benutzer nach einer Obergrenze bis zu der gesucht werden soll
    while True:
        try:
            obergrenze = int(raw_input('Bitte geben Sie eine Obergrenze ein: '))
            break
            
        except ValueError:
            print 'Dies ist keine gültige Obergrenze. Bitte verwenden Sie eine Ganzzahl!'
    
    # Jede Zahl zwischen 1 und obergrenze wird zuerst als prim angenommen
    zahlen = [True]*(obergrenze+1)
    # Da 0 und 1 keine Primzahlen sind, werden sie auf False gesetzt
    zahlen[0] = False
    zahlen[1] = False
    
    i = 2
    
    while i*i <= obergrenze:
        if zahlen[i]: # Die Zahl i ist als prim markiert
            # Streiche alle Vielfachen von i
            for k in range(i*i,obergrenze+1,i):
                zahlen[k] = False
        
        i = i+1
    
    # Ausgabe aller gefundenen Zahlen
    for i, v in enumerate(zahlen):
        if v:
            print i, 'ist prim.'
    
    return 0

if __name__ == '__main__':
    main()

Das Programm fragt zunächst nach einer Obergrenze und gibt dann alle Primzahlen bis zu dieser aus.

#include<iostream>
#include<cmath>
using namespace std;
 
int main(void){
    unsigned limit;
 
    cout << "Please insert upper limit.\n";
    cin >> limit;
 
    bool *Stroke = new bool[limit+1];
    Stroke[0]=1;
    Stroke[1]=1;
    for(unsigned i=2; i<=limit; ++i) Stroke[i] = 0;
 
    unsigned prime=2;
    while(pow((double)prime,2.0)<=limit){
        for(unsigned i = (int)pow((double)prime,2.0); i<=limit; i+=prime){
            Stroke[i]=1;
        }
 
        do ++prime; while(Stroke[prime]);
    }
 
    cout << "\nPrimes less or equal " << limit << " are:\n";
    for(unsigned i=0; i<=limit; ++i){
        if(!Stroke[i]) cout << i << endl;
    }
    delete[] Stroke;

    return 0;
}

Eine andere Variante, die neuere Sprachfeatures (Lambdas, automatische Typableitung - C++11) sowie Container und Algorithmen der Standard Template Library (STL) benutzt, ist die nachfolgende. Dabei wird das Erase-Remove-Idiom benutzt: Der STL-Algorithmus remove_if schiebt alle Elemente des std::vector-Containers, die das durch ein Lambda-Konstrukt ([p](auto q){ ... }) formulierte Teilbarkeits-Kriterium erfüllen, ans Ende des Containers und gibt einen Iterator, der auf den Anfang des zu löschenden Bereiches zeigt, zurück. Mit candidates.erase(..., end(candidates)) schließlich wird der gesamte Bereich gelöscht (was intern lediglich eine Änderung der Längen-Variablen des Containers bedeutet).

#include <iostream>
#include <iterator>
#include <vector>
#include <algorithm>
#include <numeric>

using namespace std;

vector<unsigned>  primes_upto(unsigned limit)
{
    vector<unsigned>    candidates(limit - 1);
    iota(begin(candidates), end(candidates), 2);    // candidates = 2, 3, ..., n

    auto const  upper_limit = (limit + 1) / 2;      // ceil(limit/2)

    for (auto candidate = begin(candidates);        // vector<unsigned>::iterator
         *candidate <= upper_limit;
         ++candidate)
    {
        auto const p = *candidate;                

        // 'erase-remove idiom':
        // remove_if(...) moves all multiples of p to the end and returns
        // an iterator to the beginning of the (re)moved part;
        // candidates.erase(..., end(candidates)) actually deletes these values
        candidates.erase(remove_if(candidate + 1,   // don't remove p itself
                                   end(candidates),
                                   [p](auto q){     // capture p by value
                                       return (q % p == 0);
                                   }),
                         end(candidates));

    }

    return candidates;      // copy elision guaranteed by C++ standard
}

int main()
{
    unsigned limit;
 
    cout << "Please insert upper limit.\n";
    cin >> limit;

    auto primes = primes_upto(limit);

    for (auto p : primes)
        cout << p << " ";

    cout << endl;
}

Limit heißt die Obergrenze, bis zu der alle Primzahlen ausgegeben werden.

sieb<-function(limit){
 (vek<-2:limit)[1==apply(0==outer(vek, vek, "%%"), 1, sum)]
   # Primzahlen bis limit
   # %% Division mit Rest oder modulo
}

Hier ein möglicher Quelltext eines Go-Programms zur Ausgabe der Primzahlen von 1-1000 (Der Bereich kann natürlich beliebig erweitert werden). Die Primzahlen werden dann in der Console ausgegeben. Dieses Programm kann auf der offiziellen Golang-Seite ausprobiert werden. Die Erklärungen sind identisch mit denen vom Java-Quellcode.

package main

import "math"

func main () {
	var limit uint = 1000
	var zahl, zaehler uint
	var primzahl bool
	
	for zahl = 2; zahl <= limit; zahl++ {
		
		primzahl = true
		
		for zaehler = 2; zaehler <= zahl/2; zaehler++ {
			if math.Mod(float64(zahl), float64(zaehler)) == 0 {
				primzahl = false
				break
			}
		}
		
		if primzahl == true {
			println(zahl, " ist eine Primzahl")
		}
	}
	
	
}


Literatur

[Bearbeiten]
  • The New Book of Prime Number Records, Paolo Ribenboim, Springer Verlag 1996, ISBN 0-387-94457-5
  • My Numbers, my Friends, Paolo Ribenboim, Springer Verlag, ISBN 0-387-98911-0
  • Prime Numbers - A Computational Perspective, Richard Crandall & Carl Pomerance, Springer Verlag, ISBN 0-387-25282-7

Internet

[Bearbeiten]