Primzahlen berechnen
Elektronik-Labor
Projekte
Mikrocontroller PicoBasic
Kürzlich habe ich mal auf einem VC20 versucht, ein
Basic-Programm zur Berechnung von Primzahlen zu schreiben. Ich konnte
mich erinnern, dass ich sowas auf meinem Sharp-Taschenrechner locker
hinbekommen hatte. Aber das ist lange her, und diesmal habe ich es
nicht fehlerfrei geschafft. Das hat mich gewurmt. Und deshalb habe ich
mich gefragt, ob ich es wenigstens in meinem PicoBasic schaffe.
Im ersten Versuch habe ich das Datenarray mit einer Zahlenfolge 0 bis
255 vollgeschrieben. Dann wurden in zwei Schleifen alle Zahlen
multipliziert und die Produkte als Adresspointer verwendet, um auf
diese Nicht-Primzahlen Nullen als Markierung zu schreiben. Die ganze
Sache war aber problematisch, weil ich mit Bytes rechnen musste. Wenn
ein Produkt zu groß wurde, konnte der Übertrag eine echte Primzahl
löschen. Ich habe hin und her probiert, konnte aber keine Lösung für
alle Primzahlen bis 100 finden.
Dann ist mir ein anderes Verfahren eingefallen. Um eine Zahl A zu
testen, teile ich sie durch B und multipliziere das Ergebnis wieder mit
B. Wenn das Ergebnis genau der Zahl A entspricht, war A keine Primzahl.
Beispiel: A sei 9. Ich rechne 9/2=4,5, als Ganzzahl 4, dann
4*2=8, die 9 bekommt noch eine zweite Chance: 9/3=3 und 3*3=9,
durchgefallen! Weil A und B auch noch für Vergleiche gebraucht werden,
müssen sie in D und C zwischengespeichert werden. Die 2 würde
übrigens nicht getestet und stattdessen am Anfang direkt mit Print
ausgegeben, weil sie bei den Vergleichen Probleme hatte.
REM Primzahl
L5:
0x1A01 Delay s = 1
0x0102 A = 2
0x4200 Print A
0x0103 A = 3
0x3800 D = A
0x0202 B = 2
L1:
0x3500 A = B
0x3600 C = A
0x3900 A = D
0x2D00 A = A / B
0x2C00 A = A * B
0x3400 B = A
0x3900 A = D
0x221A If A=B Goto L3:
0x3700 A = C
0x2800 A = A + 1
0x3400 B = A
0x3900 A = D
0x2218 If A=B Goto L2:
0x2006 Goto L1:
0x3700 A = C
0x2800 A = A + 1
0x3400 B = A
0x2006 Goto L1:
L2:
0x1A01 Delay s = 1
0x4200 Print A
L3:
0x3900 A = D
0x2800 A = A + 1
0x3800 D = A
0x02FF B = 255
0x2200 If A=B Goto L5:
0x0202 B = 2
0x2006 Goto L1:
Die Vergleiche steuern den Programmablauf: Wenn das Ergebnis der
Multiplikation gleich der Testzahl ist, ist sie durchgefallen, und es
geht weiter bei L3, wo A um 1 erhöht wird, um die nächste Zahl zu
testen. Wenn B so groß wird wie A, wurde offensichtlich kein Teiler
gefunden, also eine Primzahl erkannt und bei L2 mit Print ausgegeben.
Und wenn A bis 255 gekommen ist, ist die gesamte Suche abgeschlossen
und beginnt von vorn bei L5. Dass L5 ganz vorn steht, liegt daran, dass
ich alles zuerst mit End abgeschlossen hatte und dann nachträglich doch
lieber an den Anfang gesprungen bin.
Die Ausgaben im Bereich 0...255 passen gut zum Plotter im
Testlabor. Damit hat man eine einfache Möglichkeit die Verteilung der
Primzahlen zu betrachten. Ganz untern sind sie offensichtlich etwas
häufiger, denn da verläuft die Kurve flacher. Aber dann sieht es im
Bereich bis 255 fast nach einer Gleichverteilung aus. Nur knapp über
100 und dann wieder über 190 liegen einige Primzahlen dichter
beieinander.
Fazit: Ich bin zufrieden, dass ich die Aufgabe doch noch lösen konnte,
und dann auch noch mit PicoBasic. Allerdings wäre das Verfahren in
einem vollen Basic mit mehr Variablen noch eleganter zu verwenden.
Download: Primzahl.pbas
Elektronik-Labor
Projekte
Mikrocontroller
PicoBasic