Ok Leute also mir macht's super viel Spaß darüber zu sprechen
@BlackJack: du hasst recht ich habe mich um 3 Nullen vertan ( aber ich habe dies auch bei meiner Probe der Prozedur verwendet )
6510, 6502, 8510, und der Z80 stammen noch aus C64/C128 und "CPM Mallard" Zeiten die hatten tatsächlich nur ADC (Add with carry ) und SBC (subtract with carry) Befehle. Diese Prozessoren habe ich allerdings schon Ewigkeiten ( Ich hatte damals ein C116 kleiner Bruder von C64 und habe auch schon in ASM programmiert) nicht mehr gesehen, dennoch bin ich der Meinung solange ein Compiler BASIC, C, oder C++ nicht optimal in Maschinencode umsetzen kann wird die ASM Prozedur das Optimum sein. Und trotzdem konnte man auf 6502/6510 Prozessoren Multiplikationen ( mit Bitverschiebung ASL (arithmetic shift left) und bei Multiplikatoren welche nicht ein Vielfaches von 2 waren durch zusätzl. Addition des Restes) effizient durchführen. Das gleich galt auch für Divisionen LSR (Logical shift right) ( Programming 6502 von Rodnay Zaks Sybex Verlag ( nicht mehr erhältlich , falls jedoch jemand Interesse haben sollte ich habe auf jeden Fall noch ein Exemplar).
Also wie gehabt ich wollte keinen Algorithmus euch vorschlagen, wenn ich das z.B. in Python, wovon ich absolut keine Ahnung habe, hätte machen müssen dann hätte ich mit hoher Wahrscheinlichkeit auch das Sieb verwendet, allerdings hätte ich dann eine dyn. List<Int32> (Gibt's so was in Python ?)verwendet und diese quasi zur Laufzeit mit jedem gestrichenen Wert verkleinert das ich am Ende nur noch die Primzahlen hätte. Und wie du auch schon erwähnt hasst hätte ich von vornherein alle Zahlen dessen LSB = 0 einfach garnicht erst in die Liste genommen ( ausser der 2 natürlich ) Vom Algorithmus her wäre das dann noch eine Verbesserung zum normalen Sieb wo die Werte nur markiert werden und man prüfen muss ob dieser Wert in Frage kommt oder nicht. Aus dem Blickwinkel der Geschwindigkeit wäre dieses Vorgehen aber höchst wahrscheinlich langsamer als das ursprüngliche Sieb.
@Sirus3
Dadurch das sich bei jedem Schleifen durchlauf der Divisor (r10) gegenläufig zum Quotienten(rax) verhält und eine abbruch bei Divisor > Quotient erfolgt ergibt nach meiner Analyse ( muss ja nicht richtig sein du könntest mir ja deine mal aufschreiben wie du die Sache sieht ) für jede Zahl die zu überprüfen ist habe ich (Wurzel aus Zahl)-1 Divisionen durch zu führen. D.h ich ziehe nirgends im Code eine Wurzel.
Code: Alles auswählen
@Weiter:
xor rdx, rdx
MOVE_PARAM rax, 1
div r10
cmp rdx, 0
jz @NoPrime
inc r10
cmp r10, rax
jb @Weiter
Schritte beim Sieb
ÜZ Vielfache Gesamt Schritte
1 Schritt. 2 50 Schritte 51
2 Schritt. 3 33 Schritte 85
3 Schritt. 4 0 Schritte 86
4 Schritt. 5 20 Schritte 107
5 Schritt. 6 0 Schritte 108
6 Schritt. 7 14 Schritte 123
7 Schritt. 8 0 Schritte 124
8 Schritt. 9 0 Schritte 125
9 Schritt. 10 0 Schritte 126
10 Schritt. 11 9 Schritte 136
11 Schritt. 12 0 Schritte 137
12 Schritt. 13 7 Schritte 145
Schritt bedeutet : Index auf Array bilden, Prüfen ob Gelöscht oder nicht ( also ob man Vielfache ermitteln muss ), vielfache ermitteln (Wenn nötig).
Jetzt könntest du natürlich sagen Moment mal die Zahl 3 hat gar nicht so viele Schritte weil ja das Produkt 2x3 und das vielfache bereits durch die Vorherige Ermittlung gelöscht wurden, wie willst du das aber deiner Prozedur mitteilen das er diese nicht mehr prüfen muss. ( wenn du keine dyn. List verwendest ) Es sei denn du baust ein 2 Array mit allen bisher ermittelten vielfachen auf und prüfst vor deiner Prüfung ob die zu prüfende Zahl bereits in deinem Vielfach Array vorhanden ist ( wäre absolut super effizient da könnte dann auch 8-Core Parallel Threads in asm nichts mehr gegen ausrichten ) jetzt wirst du sagen warum brauche ich den bei der zu prüfenden Zahl 2 -> 50 Vielfache ? ganz einfach weil deine Abbruchbedingung > 100 sein muss nicht wegen der 2 sondern wegen der noch folgenden Zahlen welche nicht ohne Rest teilbar sind und welche wenn auch nur knapp vor der 100 und gültig und knapp nach der 100 und ungültig sind. Aber warum 51 Schritte Gesamt weil auch die Schleife ein Schritt darstellt die du für das Sieb benötigst.
ÜZ = zu überprüfende Zahl im Array
Vielfache = Anzahl Schritte Vielfache Ermittlung und Markierung
Gesamtschritte = Anzahl aus Schleifendurch und Anzahl Vielfache
Nochmal dies ist nur meine Sicht der Dinge, und keinerlei Anmaßung etwas besseres (Algorithmus) gemacht zu haben ( was ich ja auch noch nie behauptet habe ). Ich möchte nur einfach darauf hinweisen das selbst eine ineffiziente Art ( divison i.ü. bis zu 200 Taktzyklen pro DIV / IDIV ) in Maschinensprache wenn es um Geschwindigkeit geht das Maß der Dinge sein kann.
Ich bitte um Stellungnahme ( für mich ist es sehr interessant darüber zu sprechen )
Danke und Gruß
DerTürke