Wie berechnet man eigentlich eine Primzahl?

8 Antworten

zuerst prüfst du, ob die eingegebene Zahl mit Einerstelle = 0 2 4 6 oder 8 ist. Ist das der Fall hast du schonmal einen Faktor 2 und wenn die Zahl dann größer 2 war, ist sie keine Primzahl: fertig.

das selbe mit der Endziffer 5 und dem Faktor 5. Ist die Zahl dann größer 5, keine Primzahl: fertig.

dann die einzelnen Ziffern der Zahl addieren wenn diese größe 3 ist. Ist das Ergebnis ganzzahlig durch 3 teilbar, so war es keine Primzahl: MOD Funktion. fertig.

Ist der Algorithmus noch nicht fertig, dann folgendes:

starte mit Testfaktor 7

Wiederhole solange wie Testfaktor * Testfaktor <= Primzahl.

teste mit MOD Funktion ob ganzzahlig durch Testfaktor teilbar. wenn ja, dann fertig --- keine Primzahl.

Testfaktor um 2 erhöhen,

wenn wie oben durch 2, 3 oder 5 teilbar, dann erneut Testfaktor um 2 erhöhen, solange bis eben nicht durch 2,3 oder 5 teilbar.

End Wiederhole.

Zahl ist Primzahl, wenn in der Schleife kein Abbruch erfolgte.

Um das ganze zu beschleunigen kannst du noch die ersten 100 Primzahlen in ein Array speichern und dann erst das Array druchlaufen ob die Zahl drin ist. Ist sie nicht drin und kleiner der größten im Array, ist sie keine Primzahl. Ist sie drin dann ist sie Primzahl. Nur wenn die Zahl also größer der größten im Array befindlichen Zahl ist kommt dann der obige Algorithmus zum Laufen.

Problem ist jetzt nur noch der Datentyp. Für Primzahlberechnung darfst du nicht float nehmen sondern eine großen positiven int Typ. Aber selbst der größte int Typ ist evtl. zu klein. Aber ich schätze soweit will der Lehrer das nicht ausgearbeitet wissen.

zZDarkstarZz 
Fragesteller
 25.01.2019, 21:43

Heißt das, dass alle Zahlen mit 0,2,4,6,8,5 in der einerstelle keine Primzahlen sind?

1
TomRichter  26.01.2019, 21:47
@zZDarkstarZz

Vielleicht solltest Du, bevor Du ein Programm zu Primzahlen schreibst, Dir wenigstens die Grundlagen zum Thema reinziehen?

0
iqKleinerDrache  25.01.2019, 21:44

wie oben beschrieben: ausnahme natürlich die 2 und die 5 selbst sind Primzahlen.

0
iqKleinerDrache  25.01.2019, 21:46
@iqKleinerDrache

aber wie im endsatz beschrieben: das eigentliche problem wird der datentyp ... denn man will nicht etwa primzahlen bis 4 milliarden ... sondern primzahlen von 30-stelligen integern (dezimal gelesen) ... so und nun ? das wird jetzt kompliziert.

0
iqKleinerDrache  25.01.2019, 21:48
@iqKleinerDrache

lehrer also fragen ob der maximal verfügbare int datentyp den die programmiersprache bietet genügt: long unsigned int zum beispiel. wenn nicht ... dann musst du noch überstunden machen ;-)

0
iqKleinerDrache  25.01.2019, 21:56
@iqKleinerDrache

und verschwiegen soll auch nicht werden, dass es mathematishe verfahren gibt, die es noch schneller machen ... aber solange die sache mit dem datentyp bei unsigned long int bleibt spielt das dann keine rolle ,,, denn dann ists schnell genug, erst wenn du auf mind 30 stellen zahlen aufpustest solltest du dir diese mathematischen verfahren reinziehen.

0
atoemlein  26.01.2019, 00:50
@iqKleinerDrache

Es geht doch um einen kleinen lustigen Algorithmus, und sicher nicht um eine mathematisch bestoptimierte Version für Riesenzahlen.

1

eine P kann man nicht berechnen mit einer formel.

f ( P ) = .....

eine Primzahl ist dann ermittelt, wenn man festgestellt hat , daß z.B 53 durch keine ganze Zahl außer 1 und 53 teilbar ist . Dabei reicht es , durch alle ganzen und ungeraden Zahlen zu teilen , die kleiner sind als Wurzel aus (53) , also .....<= 7.

Bei 100 000 sind es "nur" 316/2.

PS : Besser als Erastothenes ist dieses Sieb

https://de.wikipedia.org/wiki/Sieb_von_Atkin

  • Falls die Testzahl eine gerade Zahl und nicht zwei ist: Keine Primzahl
  • Dann nimmst du die Wurzel der Zahl
  • Dann testest du mit allen ungeraden Zahlen von 3 bis zur Wurzel, ob Zahl MOD Testzahl verschieden 0 ist.
  • Falls alles erfüllt -> Testzahl=Primzahl

Du probierst bis maximal zur Hälfte alle Primzahlen als Teiler durch, denn das sind die Zahlen, die kein Vielfaches eines vorigen Teilers sind. Wenn keinen findest, ist  die Zahl eine Primzahl.

Beispiel:

101

Die Hälfte ist 50

Nicht teilbar durch 2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, also Primzahl.

atoemlein  26.01.2019, 00:55

Hälfte ist zuviel. Bis zur Wurzel genügt!

1
MatthiasHerz  26.01.2019, 12:05

Stimmt, das macht Sinn.

0

Hier, muss nur noch von C++ an C angepasst werden :

https://de.wikibooks.org/wiki/Algorithmensammlung:_Zahlentheorie:_Sieb_des_Eratosthenes#C++

Das Programm funktioniert, kannst du hiermit ausprobieren :

https://www.jdoodle.com/online-compiler-c++

Die Zahleneingabe muss in der Stdin Inputs... - Box erfolgen, und dann nochmal auf Execute geklickt werden.

iqKleinerDrache  25.01.2019, 22:02

das programm gibt eine liste von primzahlen aus und nicht ob die eingegebene eine primzahl ist. das gesuchte programm muss also nur eine antowrt "Primzahl", oder "keine Primzahl" geben.

0
precursor  25.01.2019, 22:03
@iqKleinerDrache

Wenn die Zahl in der Liste nicht mit dabei ist, dann ist sie auch keine Primzahl ;-))

Ist sie aufgelistet, dann ist es eine Primzahl ;-))

0
iqKleinerDrache  25.01.2019, 22:04
@precursor

ist aber blödsinn speicher zu reservieren. evtl. kackt der rechner mit out of memory ab, weil eben keine 100 billionen integer speichern kann in dem stroke.

0
iqKleinerDrache  25.01.2019, 22:11
@iqKleinerDrache

ok 100 billionen war übertrieben. aber man sollte schon zumindest die zahl: 4 milliarden eingeben können was dann bestimmt mind. 5 millionen integer primzahlen (keine ahnung wieviel genau, aber sicher mehr als zig-tausend) erzeugt. und das wird dann der rechner schon verweigern.

1
iqKleinerDrache  25.01.2019, 22:14
@iqKleinerDrache

aber für den ersten schritt meines algoritmus erstmal nicht schlecht ... dann aber nur bis maximal 1000 und nicht dauernd neu berechnen sondern einmal als seperates programm ausfühjren und die liste fest rein stellen als fix zahlen.

1
precursor  25.01.2019, 22:15
@iqKleinerDrache

Wenn du es ohne Speicher haben willst, dann geht es auch Brute-Force, hier mal ein QBASIC - Programm :

https://www.qb64.org/

DEFDBL A-Z

CLS

INPUT "Welche Zahl soll geprueft werden ( > 1) "; z

Merke = 0

FOR i = 2 TO (z - 1)

   IF INT(z / i) = (z / i) THEN Merke = 1

NEXT i

PRINT

IF Merke = 0 THEN PRINT "Die Zahl ist eine Primzahl."

IF Merke = 1 THEN PRINT "Die Zahl ist keine Primzahl."

END

Dieses Programm verbraucht praktisch keinen Speicherplatz, ist aber langsam.

Für Zahlen in der Nähe von 1000000000 werden bereits mehrere Sekunden Rechenzeit benötigt.

0
iqKleinerDrache  25.01.2019, 22:19
@precursor

ist ja auch dumm programmiert ... denn du brauchst ja nicht bis zu z-1 laufen sondern nur bis i quadrat größer gleich z ist. und dann brauchst du nicht jede zahl prüfen sondern erstmal nur jede 2te und dann keine die mit 5 ended und dessen quesrumme bereits druch 3 teilbar ist. zumindest das step 2 ist leicht hinzufügbar und würde schon die zeit halbieren. dann mit dem i quadrat nochmal merklich.

1
iqKleinerDrache  25.01.2019, 22:22
@iqKleinerDrache

achja .. und zu guter letzt: sobald Merke = 1 ist, kann von der Schleife rausgesprungen werden und muss nicht noch mehr geprüft werden. Der Datentyp ist auch bedenklich, evtl. nimmt Basic da dann float bei zwischenergebnis (z / i) und ist ungenau ... also der datentyp muss spezifiziert werden auf interger typen.

1
precursor  25.01.2019, 22:24
@iqKleinerDrache

Ja. da hast du recht, bei Merke = 1 kann man die Schleife verlassen, habe ich auf die Schnelle übersehen.

Also :

DEFDBL A-Z

CLS

INPUT "Welche Zahl soll geprueft werden ( > 1) "; z

Merke = 0

FOR i = 2 TO (z - 1)

   IF INT(z / i) = (z / i) THEN Merke = 1: EXIT FOR

NEXT i

PRINT

IF Merke = 0 THEN PRINT "Die Zahl ist eine Primzahl."

IF Merke = 1 THEN PRINT "Die Zahl ist keine Primzahl."

END

0
precursor  25.01.2019, 22:33
@iqKleinerDrache

Das mit den DEFDBL ist bei QBASIC so eine Besonderheit, das gibt es keine Probleme, DEFDBL sorgt sogar dafür dann man bis 999999999999998 gehen kann, ohne Probleme. Ist also besser als Integer.

0
precursor  26.01.2019, 09:09
@iqKleinerDrache

Und hier mit der Änderung STEP 2 die du vorgeschlagen hast :

DEFDBL A-Z

CLS

INPUT "Welche Zahl soll geprueft werden ( > 1) "; z

Merke = 0

FOR i = 2 TO (z - 1) STEP 2

   IF INT(z / i) = (z / i) THEN Merke = 1: EXIT FOR

NEXT i

PRINT

IF Merke = 0 THEN PRINT "Die Zahl ist eine Primzahl."

IF Merke = 1 THEN PRINT "Die Zahl ist keine Primzahl."

END

0
precursor  26.01.2019, 09:17
@precursor

Anmerkung :

Die Rechenzeit ist bis etwa 10000000019 erträglich, also im 10 Milliarden-Bereich.

Und das Programm liefert auch das korrekte Ergebnis, dass das eine Primzahl ist.

0