Zitat:
Fehler beim Anfordern des benötigten Speichers, Programm wird beendet.
Das ganze kam innerhalb des Programmes, richtig? Ich habe da eine kleine Überprüfung reingebaut, nämlich nach dem der Speicher angefordert wird, wird geschaut ob dieser Vorgang gelungen ist oder nicht.
Der Hauptgrund wieso dies misslingen sollte, ist wenn das Programm versucht einen größeren Speicher anzufordern als zusammenhängend verfügbar.
Hast du ggf. die Auslagerungsdatei deaktiviert? Hattest du einen Haufen Anwendungen oder ein paar wenige Speicherlastige Anwendungen laufen? Ansonsten wenn das nicht zutrifft, hat es Windows einfach nicht geschafft den Speicher so umzustrukturieren, dass ein so großer Speicherbereich verfügbar war. Denn der Speicher fragmentiert nach der Zeit aus, es kann zwar sein, dass du genug Speicher frei hattest aber eben nicht genug an einem Stück.
Probier einfach mal es nochmal auszuführen, ggf. mit weniger Programmen im Hintergrund und ggf. mit aktivierter Auslagerungsdatei, dann wird entweder der Rest ausgelagert oder mein Arrays in dieser erstellt.
Zitat:
Mich würde sehr interessieren, wie hier die Statistik für 10, 100, 1000, ... Ausgangszahlen aussieht.
Das wäre auch ein sehr gutes Kriterium, um deine Algorithmen gegeneinander zu vergleichen - unabhängig von der verfügbaren Techenleistung.
Das ist so leider nicht ganz möglich, denn V2 und V3 prüfen beide gleich oft (sofern ich bei V2 das mit der Wurzel integriert habe aber das hatte ich bei V2 wenn es nicht drin ist einfach nur vergessen, der Rest ist zumindest identisch ausser, wie die Sachen gespeichert werden.) Was noch hinzukommt ist, dass ich bei V2 und V3 gar nicht teste ob eine Primzahl durch irgendwas teilbar ist. Sondern einfach alle vielfachen von einer Zahl rausnehme und da ist das Verfahren bei V2 und V3 identisch, dieses Verfahren ist auf jedenfall schneller als das in V1 welches noch alles durchprobierte.
Oder du meintest wie viele Rechenzyklen meine Algorithmen brauchen, das Problem hierbei ist jedoch, dass dies nicht so einfach ermittelt werden kann. Denn 1. müsste ich wissen was GENAU mein Compiler aus dem C Code macht was innerhalb von C eigentlich unmöglich ist. In
Assembler wäre dies kein Problem, da jeder Befehl in einen Maschinencode umgewandelt wird und da die Anzahl der Taktzyklen rausgefunden werden kann. Das 2. Problem ist, dass jeder eine andere Architektur besitzt und so eine gewisse Anweisung von einem Prozessor vielleicht 2 Takte braucht und beim anderen 4 Takte damit diese Anweisung ausgeführt werden kann (Stichwort CPU-Optimierung). Ausserdem wird mein Programm nicht direkt von der Hardware ausgeführt, denn es sind noch ein paar Schichten vom Betriebssystem dazwischen und das bedeutet, dass ein Algorithmus der theoretisch flotter ist, praktisch langsamer sein kann.
Es ist also vollkommen sinnlos zu messen wie oft ein Programm was macht das einzige was bei einem solchen Algorithmus zählt ist wie schnell dieser im Endeffekt ist und das mache ich ja eigentlich schon mit meiner Zeitmessung.
Ausserdem wüsste ich gar nicht wann ich eine Variable hochzählen sollte, damit man diese statistisch sinnvoll verwerten könnte, besonders nicht bei 2 vollkommen unterschiedlichen Algorithmen wie V1 und V2.
Zitat:
Hmm, das mit dem Sieb einfach versetzen hört sich gut an. Doch (bitte nicht hauen wenn ich mich irre) hat folgendes Problem: Wenn ich nun die Zahlen von 1 bis 100 siebe, ist der erste Platz keine Primzahl. Doch wenn ich das gleiche Sieb nun auf die Zahlen von 101 bis 200 anwende, wäre auch 101 keine Primzahl. (Das ist doch eine oder :lol: )
Naja das mit der 1 wäre absolut kein Problem, ich nehme einfach ein Array mit 1-100 und frage diesen einen besonderen Fall ab und wenn das zutrifft vermerke ich 1 als nicht Primzahl und 2 als Primzahl.
Das Problem hierbei ist, dass das mit dem verschieben des Gitters einfach nicht funktioniert!
Nehmen wir ein Gitter von 1-10:
1 = nicht prim
2 = prim
3 = prim
4 = nicht prim
5 = prim
6 = nicht prim
7 = prim
8 = nicht prim
9 = nicht prim
10 = nicht prim
und versetzen das nun auf 11-20, dann hätte ich folgendes:
11 = nicht prim
12 = prim
13 = prim
14 = nicht prim
15 = prim
16 = nicht prim
17 = prim
18 = nicht prim
19 = nicht prim
20 = nicht prim
Hier sehe ich, dass ich bei 11 nicht Prim stehen habe und bei 15 Prim was beides falsch ist und somit hätte ich das Problem, dass ich bei keiner der Zahlen nun wirklich weis ob Prim oder nicht Prim, da beides möglich ist und so müsste ich beide darauf testen ob oder ob sie nicht Prim sind und dadurch hätte ich absolut keine Vorteile. Und sowas entsteht auch bei einem Gitter von 100, von 1000 oder bei jeder x-beliebigen Gittergröße.
Aber mir ist ein anderer alternativer Algorithmus eingefallen. Denn es gilt ja, dass jede natürliche Zahl größer als 1, als Produkt einer Primzahl dargestellt werden kann. Bei Primzahlen ist aber das einzige mögliche Produk 1*sich selbst(was eine Primzahl ist).
Der Algorithmus würde also bei 2 anfangen und schauen ob es eine Primzahl gibt mit der Multipliziert werden kann (nämlich durch eine Division). Da es keine gibt (weil bisher keine gefunden wurden), ist 2 eine Primzahl. Dann wird bei 3 getestet und geschaut ob eine andere Primzahl reinpasst 3/2 != x€N also nein. Dann wird bei 4 getestet und hier sieht man sofort 4/2=2 also keine Primzahl und ab zur nächsten Zahl.
Wenn ich nun rausfinden könnte wie viele Primzahlen es maximal gibt bei einer gewissen Grenze könnte ich auch nur maximal so viel Speicher anfordern.
Dies wäre zwar rechenintensiver als V2 und V3, aber weniger speicherlastig, da nur die Primzahlen gespeichert werden und maximal so viel Speicher belegt wird wie maximal Primzahlen vorhanden sind, sofern ich rausfinden kann wie ich das berechne, diesen Speicher könnte ich theoretisch anfangs erst klein halten und später ständig erweitern und beim Auslagern wäre der Algorithmus sogar schneller, da jeder Wert nur einmal in die Berechnung reingenommen wird und nicht ständig ein ganzer Haufen an Werten aktualisiert wird.
Es ist eine Art Kombination aus beiden Verfahren.