Seite 4 von 5

Re: Und nun ein C++-Problem...

Verfasst: 30.01.2010 19:04
von P7BB
Okay, ich hab das ganze nun mit einer For-Schliefe bei "CreateThread" synchronisiert. Ich bin nun auch schon fast an dem "ultimativem" primzahl-programm dran, aber dummerweise wird immer nur die erste Primzahl (=3; weil a mit 3 initialisiert wird) gefunden.
a wird auch korrekt in allen Threads "erhöht" und es gibt keine doppelten berechnungen oder ähnliches, nur anscheinend wird hier irgendeine variable nicht zurück auf 0 gesetzt, da dort zwar "b" immer den korrekten wert hat, aber trotzdem primzahlen nicht mehr ausgegeben werden.

Code: Alles auswählen

// Thread 1
long WINAPI thread1() {
 int b = a;
 cout << b << " Thread 1" << endl;
 a = a + 2;
 int c = 1000000;
 int d = 0;
 double mi;
 boolean prim = true;
 mi = sqrt(b);
 for(d = 2;d <= mi;++d) {
  if(b / d == ceil(b / d)) {
   prim = false;
  }
 }
 if(prim == true) {
  cout << b << " Thread 1" << endl;
  f << b << endl;
 }
 return 0;
}
Edit: Erledigt! Ich musste d als double definieren, weil wenn sowohl b, als auch d als int definiert worden wären, würde auch nur ein int rauskommen ;)

Edit2: Ok, das Primzahl-Programm arbeitet nun mit 8 Threads und schafft so in der ersten Sekunde etwas über 1140 Primzahlen ;) Danke für die ganze Hilfe, ich glaub, ohne dich wär ich echt aufgeschmissen gewesen! ;) :) :D

Re: Und nun ein C++-Problem...

Verfasst: 30.01.2010 23:45
von gn#36
Na dann ist ja gut. Wofür brauchst du den Kram überhaupt? Wenn ich Primzahlen brauche, dann meist eigentlich meist nur eine in einer gewissen Größe.

Woran du wie gesagt noch arbeiten musst sind große Primzahlen. Das wird ohne entsprechende Bibliothek nichts, denn sowohl Doubles als auch integer und long haben ihre Grenzen, ab einer gewissen Größe werden deine Berechnungen falsch, egal ob du einen oder acht Threads benutzt. Irgendwann kommt dir der Overflow in die Quere und plötzlich ist 2147483647 + 1 nicht mehr 2147483648 sondern -2147483648 (bei einer Integer Größe von 32 bit).

Re: Und nun ein C++-Problem...

Verfasst: 31.01.2010 00:09
von P7BB
Ich brauch die Primzahlen für einen Sicherheitsalgorythmus... Aber dafür brauch ich noch größere Primzahlen als die von 1-1.000.000 ;)
Außerdem ist sowas nicht grad unpraktisch, wenn man das mal im Info-Unterricht dem Lehrer zeigt... Wobei die Schul-Pcs vermutlich abstürzen :D

Aber zu den Int's: Würde ein long int nicht schon reichen, damit ich etwas höhere Zahlen berechnen kann?

Ansonsten möchte ich noch kurz erläutern, wieso ich zum Beispiel das mit den Argumenten im Dateipfad wissen wollte:
Ich möchte mit Delphi das Programm "füttern". Mit Delphi mach ich dann eine Benutzeroberfläche und sowas (weil es dort einfach viel einfacher geht) und werde dann das C++-Programm zur Berechnung benutzen, weil Delphi ganz einfach zu langsam für sowas ist. Letztendlich war das C++-Programm umfangreicher, als ich dachte, aber ich hab ja dank deiner Hilfe hinterher alle Fragen von mir beantworten können und jetzt fehlt nur noch das Delphi-Programm, womit das C++-Programm gestartet wird. So hab ich die Geschwindigkeit von C++ und das "Design" von Delphi. Natürlich könnte man auch eine Benutzeroberfläche in C++ machen, aber das würde das Programm vermutlich wieder etwas verlangsamen und es ist ja auch nicht nötig, da man die Oberfläche ja im Prinzip nur zum starten des Programms braucht, damit das etwas "komfortabler" ist.
Ansonsten würden so einige Leute, die ich kenne, rummeckern, dass das ganze doch "nur" eine Konsolenanwendung wäre, obwohl sie nicht wüssten wieviel Arbeit da für mich (und dich xD) hintergesteckt hat. ;)

Re: Und nun ein C++-Problem...

Verfasst: 31.01.2010 02:11
von gn#36
Naja nachdem du dich ja nun mit Multithreading auskennst kannst du ja auch einen Thread bauen der die Oberfläche darstellt (das solltest du sogar, denn wenn du das nicht tust friert die GUI während der Berechnung ein, auch wenn das natürlich bedeutet, dass sie keine Ressourcen frisst). Wenn du vernünftige Bibliotheken für die Oberfläche benutzt ist das auch nicht sonderlich schwierig, GTK+, QT oder - sofern du Visual Studio verwenden solltest auch die Microsofteigenen Bibliotheken sind nicht all zu schwierig. Pauschal lässt sich jedenfalls auch nicht sagen was mehr bremst, das hängt vor allem davon ab wie viele Ressourcen die GUI frisst. Je aufwändiger die Gui desto stärker bremst sie würde ich sagen. Ich kann zwar nicht beurteilen wie viel Overhead ein Delphi Programm produziert, ein Thread dürfte aber jedenfalls deutlich effizienter sein als ein eigener Prozess, denn bei dem Wechsel auf einen anderen Prozess muss der andere Prozess unterbrochen werden, die Register kopiert und der neue Prozess gestartet werden, außerdem müssen ggf. Speicherseiten ausgetauscht werden. Zumindest letzteres fällt bei einer threadbasierten Version weg (auf den anderen Thread muss ja trotzdem noch gewechselt werden). Aus dem Grund ist es auch nicht sinnvoll für ein und die selbe Berechnung mehr Threads zu verwenden als Kerne zur Verfügung stehen. Jeder weitere Thread bremst nur, denn es muss ja zusätzlich gewechselt werden. Trotzdem bremst ein separater Prozess mehr, also würde ich sagen, wenn du es mit einer effizienten GUI Programmieren willst, dann nimm einen Thread und nicht Delphi.

Solltest du Visual Studio haben oder eine der oben genannten Bibliotheken verwenden, dann dürftest du auf die eine oder andere Weise dir die GUI sogar zusammenklicken können und dann nur noch auf die Events reagieren müssen (bei GTK+ gibt's z.B. Glade, in Visual Studio ist was entsprechendes integriert und es würde mich sehr wundern wenn es irgendwie sowas für QT nicht auch gäbe).

Long int reicht nur ein bisschen länger als int, stößt aber irgendwann auch an seine Grenzen, wenn du wirklich Verschlüsselung damit betreiben willst brauchst du vermutlich Primzahlen mit einigen hundert Stellen, da reicht das auch nicht mehr. Such einfach mal nach Big Integer c++ da sollte sich einiges an Bibliotheken finden, wenn du dann deine Primzahlprüfung auf den Modulo Operator umbaust wie das schon vorher diskutiert wurde, dann brauchst du vermutlich nicht mal selbst irgendwelche Änderungen an den Bibliotheken machen.

Wer der Meinung ist, dass ein Konsoleprogramm allgemein schwächer ist als eines mit GUI, dann zeigt er damit nur, dass er absolut keine Ahnung von Computern hat. Denn erstens kann man sowas nie pauschal beurteilen und zweitens sind Konsoleprogramme spätestens wenn man weitergehende Automatisierung oder blitzschnelle Bedienung wünscht absolut unschlagbar - nicht umsonst arbeiten die meisten Server Admins mit Konsolen und auch eine Reisebürokette und eine Versicherungsgesellschaft denen ich zufällig mal auf den Bildschirm blicken durfte hatten dort "nur" einen Konsolecursor blinken. Dafür muss man dann die Hand nicht mehr von der Tastatur nehmen um das Programm zu bedienen und wenn man einen Befehl zum 100x mal verwendet hat kann man ihn spätestens auch blind auswendig und bei logischer Programmführung geht das ganze dann auch 100x so schnell wie wenn man sich mit einer Maus durchklicken müsste. Das ist nichts für ein Programm das man nur ein mal im Jahr braucht - aber wenn man ein Programm täglich einsetzt ist es eine enorme Erleichterung.

Aus dem Grund ist Konsistenz bei Programmen die man einsetzt auch enorm wichtig. Wenn man es gewöhnt ist mit der Tastenkombination Strg + C den gewählten Abschnitt zu kopieren dann stört es natürlich enorm wenn das dazu führt dass das Programm beendet wird. Genauso ist es andersherum (und beide Szenarien sind Täglich Brot für viele Leute, denn in Konsolen hat Strg + C die eine, in GUIs die andere Bedeutung, jedenfalls meistens). Wenn du also mehr Programme schreibst, dann solltest du versuchen dich an gewisse Konventionen zu halten, dadurch kommen die Leute viel schneller mit deinem Programm klar als wenn du das Rad neu erfindest was die Bedienung angeht.

Die Krone des ganzen sind dann die alten VIM Meister, die - während man noch überlegt wie der Dateiname der Datei war die er gerade aufgerufen hat - schon in drei weiteren Dateien irgendwelche komplizierten Suchen und Ersetzungen durchgeführt hat.

Re: Und nun ein C++-Problem...

Verfasst: 31.01.2010 11:36
von P7BB
gn#36 hat geschrieben:Naja nachdem du dich ja nun mit Multithreading auskennst kannst du ja auch einen Thread bauen der die Oberfläche darstellt (das solltest du sogar, denn wenn du das nicht tust friert die GUI während der Berechnung ein, auch wenn das natürlich bedeutet, dass sie keine Ressourcen frisst). Wenn du vernünftige Bibliotheken für die Oberfläche benutzt ist das auch nicht sonderlich schwierig, GTK+, QT oder - sofern du Visual Studio verwenden solltest auch die Microsofteigenen Bibliotheken sind nicht all zu schwierig. Pauschal lässt sich jedenfalls auch nicht sagen was mehr bremst, das hängt vor allem davon ab wie viele Ressourcen die GUI frisst. Je aufwändiger die Gui desto stärker bremst sie würde ich sagen. Ich kann zwar nicht beurteilen wie viel Overhead ein Delphi Programm produziert, ein Thread dürfte aber jedenfalls deutlich effizienter sein als ein eigener Prozess, denn bei dem Wechsel auf einen anderen Prozess muss der andere Prozess unterbrochen werden, die Register kopiert und der neue Prozess gestartet werden, außerdem müssen ggf. Speicherseiten ausgetauscht werden. Zumindest letzteres fällt bei einer threadbasierten Version weg (auf den anderen Thread muss ja trotzdem noch gewechselt werden). Aus dem Grund ist es auch nicht sinnvoll für ein und die selbe Berechnung mehr Threads zu verwenden als Kerne zur Verfügung stehen. Jeder weitere Thread bremst nur, denn es muss ja zusätzlich gewechselt werden. Trotzdem bremst ein separater Prozess mehr, also würde ich sagen, wenn du es mit einer effizienten GUI Programmieren willst, dann nimm einen Thread und nicht Delphi.
Achso, also wäre es letztendlich dann vielleicht doch mit C++ besser...
Solltest du Visual Studio haben oder eine der oben genannten Bibliotheken verwenden, dann dürftest du auf die eine oder andere Weise dir die GUI sogar zusammenklicken können und dann nur noch auf die Events reagieren müssen (bei GTK+ gibt's z.B. Glade, in Visual Studio ist was entsprechendes integriert und es würde mich sehr wundern wenn es irgendwie sowas für QT nicht auch gäbe).
Ich hatte mir Micrsofot Visual Studio C++ installiert, aber immer, wenn ich ein Formular erstellen wollte, gab es eine Fehlermeldung vom Programm. Habs deswegen auch vor 2-3 Wochen wieder deinstalliert... Aber dann guck ich mal, wie das mit GTK+ und Glade ist ;)
Long int reicht nur ein bisschen länger als int, stößt aber irgendwann auch an seine Grenzen, wenn du wirklich Verschlüsselung damit betreiben willst brauchst du vermutlich Primzahlen mit einigen hundert Stellen, da reicht das auch nicht mehr. Such einfach mal nach Big Integer c++ da sollte sich einiges an Bibliotheken finden, wenn du dann deine Primzahlprüfung auf den Modulo Operator umbaust wie das schon vorher diskutiert wurde, dann brauchst du vermutlich nicht mal selbst irgendwelche Änderungen an den Bibliotheken machen.
Naja, also mir reichen vorerst schon die Primzahlen bis 1.000.000.000 und für diese brauch ich ja vorerst keine anderen Bibliotheken. Aber ich werds im Kopf behalten, um dann später eventuell das Programm doch noch umzustellen ;)
Wer der Meinung ist, dass ein Konsoleprogramm allgemein schwächer ist als eines mit GUI, dann zeigt er damit nur, dass er absolut keine Ahnung von Computern hat. Denn erstens kann man sowas nie pauschal beurteilen und zweitens sind Konsoleprogramme spätestens wenn man weitergehende Automatisierung oder blitzschnelle Bedienung wünscht absolut unschlagbar - nicht umsonst arbeiten die meisten Server Admins mit Konsolen und auch eine Reisebürokette und eine Versicherungsgesellschaft denen ich zufällig mal auf den Bildschirm blicken durfte hatten dort "nur" einen Konsolecursor blinken. Dafür muss man dann die Hand nicht mehr von der Tastatur nehmen um das Programm zu bedienen und wenn man einen Befehl zum 100x mal verwendet hat kann man ihn spätestens auch blind auswendig und bei logischer Programmführung geht das ganze dann auch 100x so schnell wie wenn man sich mit einer Maus durchklicken müsste. Das ist nichts für ein Programm das man nur ein mal im Jahr braucht - aber wenn man ein Programm täglich einsetzt ist es eine enorme Erleichterung.
Meine Meinung, aber nicht die Meinung von diversen anderen Leuten :(
Ich persönlich finde sogar Batch-Dateien schon recht praktisch, da diese ja auch sehr einfach funktionieren... Bei meinem Praktikum hatte ich sogar mal eine Batch-Datei geschrieben, die im Krankenhaus jetzt bei allen PCs eingesetzt wird. War jetzt nur eine "kleinere" Sache, weil nur die IPs und die Computernamen und noch ein paar Informationen mehr (vnc viewer installer[ja/nein]) rausgefunden werden sollten und auf dem server in einem extra ordner gespeichert werden sollten, aber ich bin trotzdem stolz drauf :D :D
Aus dem Grund ist Konsistenz bei Programmen die man einsetzt auch enorm wichtig. Wenn man es gewöhnt ist mit der Tastenkombination Strg + C den gewählten Abschnitt zu kopieren dann stört es natürlich enorm wenn das dazu führt dass das Programm beendet wird. Genauso ist es andersherum (und beide Szenarien sind Täglich Brot für viele Leute, denn in Konsolen hat Strg + C die eine, in GUIs die andere Bedeutung, jedenfalls meistens). Wenn du also mehr Programme schreibst, dann solltest du versuchen dich an gewisse Konventionen zu halten, dadurch kommen die Leute viel schneller mit deinem Programm klar als wenn du das Rad neu erfindest was die Bedienung angeht.
Ja, aber ich habe sowieso erstmal nicht vor, Tastenkombinationen zu definiern, weil die brauch man für mein Programm nun wirklich nicht. ;)
Die Krone des ganzen sind dann die alten VIM Meister, die - während man noch überlegt wie der Dateiname der Datei war die er gerade aufgerufen hat - schon in drei weiteren Dateien irgendwelche komplizierten Suchen und Ersetzungen durchgeführt hat.
Hm, ist das jetzt gut oder schlecht? :D

Achja: Hab mir jetzt Glade und GTK+ für Windows runtergeladen. In den Zip-Ordnern waren keine Installer, also hab ich auf dem desktop einfach den ordner "Glade" erstellt und dort die entsprechenden dateien alle reingetan. Sowohl von Glade, als auch die von GTK+. Wenn ich nun die Datei "glade-3.exe" im bin-Ordner ausführen möchte, kommt eine Fehlermeldung, weil libatk-1.0-0.dll nicht gefunden werden kann.
Brauch ich erst ein anderes Programm oder sowas, oder wieso fehlen bei mir Dateien?
Ich hab sowohl mit GTK+, als auch mit Glade noch nich was zu tun gehabt, also sorry für diese dumme Frage... ;)

Re: Und nun ein C++-Problem...

Verfasst: 31.01.2010 23:11
von gn#36
Das ist gut für die vim Meister.

Glade ist ein Programm mit GTK+ Oberfläche (wen wundert's), daher musst du die GTK+ Runtimes natürlich auch installieren um das Programm zum laufen zu bringen. Das gibt's an allen Ecken und Enden da das z.b. auch von Gimp benötigt wird (da kommt's ja ursprünglich auch her), z.b. meine ich auch hier: http://www.gtk.org/download-windows.html (Development Files sollten da auch mit dabei sein.)

Wenn du lieber die objektorientierte Variante haben willst dann schau dir vor allem auch gtkmm an, das ist die C++ Variante von GTK+ (das Basispaket von GTK brauchst du aber mit Sicherheit trotzdem): http://gtkmm.org/

Ob du GTK+ oder GTKmm benutzt ist deinem Geschmack überlassen, beide sind kompatibel zu dem Output von Glade (bzw. der Output lässt sich ggf. sehr leicht anpassen/steuern).

Es gibt auch ein paar passable Tutorials zu beiden: http://library.gnome.org/devel/gtk-tutorial/2.17/ http://library.gnome.org/devel/gtkmm-tutorial/unstable/
Wenn du ein bisschen suchst kannst du glaube ich auch was auf deutsch finden.
Die fangen beide mit ziemlich grundlegendem Krams an der aber trotzdem zu empfehlen ist, irgendwann später kommen sie auch zur Kombination von Glade und GTK+.

Re: Und nun ein C++-Problem...

Verfasst: 17.03.2010 21:36
von P7BB
Hi,
ich habe ein weiteres Problem:
Es gibt ja die Funktion cos(), aber gibt es auch sowas wie cos^-1()? Über Google habe ich nichts brauchbares gefunden, denn dort habe ich nur gelesen, dass cos^-1 = 1 / cos ist, aber das stimmt!
acos() ist ebenfalls ein anderes Ergebnis, als mein Taschenrechner es mir sagt. :(

Edit: Hierbei handelt es sich jetzt um ein neues Problem. Hat also nichts mehr mit Primzahlen zu tun ;)

Re: Und nun ein C++-Problem...

Verfasst: 17.03.2010 23:09
von gn#36
Ich glaube dabei handelt es sich vor allem um ein Verständnisproblem...

y = acos(x) ist die Umkehrfunktion des cosinus. 1/cos(x) ist genau das was da steht, der Kehrwert vom Cosinus. Allerdings musst du beachten in welchem Maß du rechnest. Die meisten Systeme arbeiten mit dem Bogenmaß, nicht dem Gradmaß wie der übliche Taschenrechner in seiner Standardeinstellung. Das ist für fast alle Anwendungen besser so. Die Funktion arbeitet völlig korrekt wenn du sie mit den richtigen Daten fütterst. acos(0) sollte pi/2 sein, acos(1) auch weiterhin 0. Umrechnung ins Gradmaß: x * 180 / pi

Das musst du auch beachten bei der Benutzung von cos() oder sin() oder allen anderen Winkelfunktionen. Du musst alle Winkel erst ins Bogenmaß umrechnen wenn sie im Gradmaß sind.

Re: Und nun ein C++-Problem...

Verfasst: 18.03.2010 13:35
von P7BB
okay, also wäre das, was ich in meinem taschenrechner als cos^-1(0.5) eingebe, dann für den PC 1/cos(0.5*180/PI) ?
Hatte zwar gewusst, dass es verschiedene "Maße" gibt, aber ich dachte bei Funktionen wie dem Sinus, Kosinus und Tangens würde das automatisch umgerechnet werden ;)
Danke!

Edit: Bei meinem Beispiel mit 0.5 kommt 60 raus, bei meinem Programm aber jedoch 1.irgendwas :(

Re: Und nun ein C++-Problem...

Verfasst: 18.03.2010 23:05
von gn#36
Dein Taschenrechner benutzt das Gradmaß, der PC das Bogenmaß. Im Gradmaß ist eine Umdrehung 360°, im Bogenmaß hingegen 2*pi. Du hast also genau falschherum umgerechnet. Du musst dem PC die Daten im Bogenmaß liefern. Die Rückgabewerte der acos / asin /atan Funktionen musst du so herum umrechnen wie du es getan hast wenn du Daten im Gradmaß haben willst. Automatisch geht da nichts, woher soll der PC denn wissen dass du ausgerechnet das Gradmaß haben willst und nicht wie üblich das Bogenmaß?