Erstes Programm mit Klasse - sinnvoll?



  • Einzig noch zwei Minianmerkungen, das ist aber eher eine Geschmackssache, nach meiner Erfahrung erhöht dies in großen Projekten aber die Lesbarkeit etwas.

    1. ich habe public:/private nicht auf der gleichen Ebene wie die Methoden/Attribute (Von der Einrückung her ist dies schneller zu erkennen, was zu welchen Teil gehört).

    2. hinter if/else schreibe ich aus dem gleichen Grund niemals direkt die Anweisung in die gleiche Zeile, selbst bei 1-Zeilen Anweisungsblöcken (Statt dessen eingerückt in Nächster). Auch wenn ich ursprünglich hier keinen Unterschied beim Lesen erwartet hätte, ist mir beim schnellen Fehlersuchen ohne die Einrückung etwas einmal entgangen.

    Zudem würde ich dir davon abraten Tabulatoren in dem Forum zu verwenden (in den meisten Projekten, in denen ich gearbeitet habe wurde auch der Tabulator immer durch eine fixe Leerzeilenanzahl ersetzt).

    alaundo schrieb:

    pow(y,2) solltest du schleunigst durch y*y ersetzen. Das dürfte deutlich schneller sein.

    Tatsächlich, aber warum?

    Ich weiß nicht ob die Aussage stimmt, könnte mir es aber gut vorstellen. Bei ^2 kann man auf eine Multiplikation ausweichen (Spezialfall), pow ist aber für den allgemeinen Fall mit beliebigen Exponenten ausgelegt, und die Berechnung könnte aufwendiger sein.



  • camper schrieb:

    alaundo schrieb:

    double pi = 4.0*treffer/wuerfe;		//mal 4 wegen Wurf auf Viertelkreis
    

    Mit diesem Kommentar stimmt etwas nicht. Wäre der Faktor wirklich ein anderer, wenn die Würfe auf den Vollkreis oder z.B. nur auf einen 1/8-Kreissektor (im Dreieck mit y <= x) erfolgen würden?

    Eigentlich wird ja nicht auf den Viertelkreis sondern auf das Einheitsquadrat geworfen. Und das überdeckt halt nur einen Viertelkreis, sodass im Endeffekt pi/4 angenähert wird, also stimmt das schon, glaube ich.



  • pow ist für ganzzahlige Exponenten nicht effizient. Deshalb sollte man es nur für Exponenten vom Typ float/double benutzen.

    Statt den Zufallswert durch Multiplikation und Division auf 3 Nachkommastellen zu runden, könntest du gleich Integer-Werte von 0-1000 nehmen. Dadurch sparst du dir die Fließkommaberechnungen und Ungenauigkeiten. Dementsprechend wird auch die Berechnung ob innerhalb des Einheitskreises effizienter.



  • oenone schrieb:

    pow ist für ganzzahlige Exponenten nicht effizient. Deshalb sollte man es nur für Exponenten vom Typ float/double benutzen.

    Und was ist bei x^84287423784278342378 ?
    Manuell ausschreiben?
    Schnell nen for-Loop schreiben (vllt mit Funktion)?
    std::pow benutzen?



  • huppel schrieb:

    camper schrieb:

    alaundo schrieb:

    double pi = 4.0*treffer/wuerfe;		//mal 4 wegen Wurf auf Viertelkreis
    

    Mit diesem Kommentar stimmt etwas nicht. Wäre der Faktor wirklich ein anderer, wenn die Würfe auf den Vollkreis oder z.B. nur auf einen 1/8-Kreissektor (im Dreieck mit y <= x) erfolgen würden?

    Eigentlich wird ja nicht auf den Viertelkreis sondern auf das Einheitsquadrat geworfen. Und das überdeckt halt nur einen Viertelkreis, sodass im Endeffekt pi/4 angenähert wird, also stimmt das schon, glaube ich.

    Es wurde ja nicht der Code beanstandet, sondern der Kommentar.
    Würden die Darts auf [-1,1]x[-1,1] geworfen, würde trotzdem pi/4 angenähert.
    Hat mit dem Viertelkreis im Kommentar nix zu tun.



  • Hallo zusammen!

    Mit diesem Kommentar stimmt etwas nicht. Wäre der Faktor wirklich ein anderer, wenn die Würfe auf den Vollkreis oder z.B. nur auf einen 1/8-Kreissektor (im Dreieck mit y <= x) erfolgen würden?

    Ja, beispielsweise 1/8-Kreissekter im Einheitsquadrat hat genau den halben Flächeninhalt, dementsprechend würde pi/8 angenähert (liefert mein Programm auch 👍 ). Dass es vom Winkel abhängt sieht man schon daran, dass bei sehr sehr kleinen Winkeln die Trefferchance auch nur noch sehr klein ist, also ein größerer Faktor multipliziert werden muss.

    Klar: wenn ich den Vollkreis im (vergrößerten) Quadrat nehme, bleibt der Faktor 1/4.

    Danke für die Tipps mit pow, ich werde wohl einfach die Multiplikationen, die man noch schnell aufschreiben kann, mit * machen, und bei Fließkommazahlen oder großen Potenzen mit pow. Wie würde das bei Zweierpotenzen mit << gehen?

    Die anderen Anmerkungen (Einrückungen, if-Schleife bei 0, Einrückung und Tabulatoren) baue ich ein.

    Danke!
    alaundo



  • alaundo schrieb:

    if-Schleife

    if != Schleife 😉



  • Äh ja, klar :p



  • Die << und >> sind Bitshiftoperatoren:

    for(unsigned int i = 0; i < sizeof(unsigned int)*8; ++i)
        std::cout << (1 << i) << " vs. " << std::pow(2, i) << std::endl;
    

    Es werden die Bits eines Datums einfach nach links* geschoben. Praktische ist das eine Multiplikation* mit der i-ten Zweierpotenz. Dabei gibt es dann noch so Späße, was mit Vorzeichen passiert oder bei Überläufen.

    Meiner Erfahrung nach braucht man das relativ selten. Und wenn mans braucht, dann weiss mane rstens schon ziemlich genau was man macht. In den meisten anderen Fällen kann der Compiler das selsbt einbauen (z.B. bei einer simplem Multiplikation/Division mit 2).

    *: rechts bzw. Division



  • Skym0sh0 schrieb:

    Die << und >> sind Bitshiftoperatoren:

    for(unsigned int i = 0; i < sizeof(unsigned int)*8; ++i)
        std::cout << (1 << i) << " vs. " << std::pow(2, i) << std::endl;
    

    Hier war '\n' statt endl gemeint.



  • volkard schrieb:

    Skym0sh0 schrieb:

    Die << und >> sind Bitshiftoperatoren:

    for(unsigned int i = 0; i < sizeof(unsigned int)*8; ++i)
        std::cout << (1 << i) << " vs. " << std::pow(2, i) << std::endl;
    

    Hier war '\n' statt endl gemeint.

    Ich weis das wurde schon öfters diskutiert, aber können wir nicht mal schön sauber zusammenfassen was die Vor- und Nachteile sind. Manche hier im Forum sind ja der Meinung, dass endl am besten komplett aus dem Standard gestrichen wird...



  • Skym0sh0 schrieb:

    volkard schrieb:

    Skym0sh0 schrieb:

    Die << und >> sind Bitshiftoperatoren:

    for(unsigned int i = 0; i < sizeof(unsigned int)*8; ++i)
        std::cout << (1 << i) << " vs. " << std::pow(2, i) << std::endl;
    

    Hier war '\n' statt endl gemeint.

    Ich weis das wurde schon öfters diskutiert, aber können wir nicht mal schön sauber zusammenfassen was die Vor- und Nachteile sind. Manche hier im Forum sind ja der Meinung, dass endl am besten komplett aus dem Standard gestrichen wird...

    Sobald ich nicht nur cout verwende, muss ich mir endl wieder abgewöhnen. Wozu es Einsteigern vorher angewöhnen, das ist nicht nett.
    http://www.aristeia.com/Papers/C++ReportColumns/novdec95.pdf
    Ja, ich würde endl als gestrichen ansehen.


  • Mod

    volkard schrieb:

    http://www.aristeia.com/Papers/C++ReportColumns/novdec95.pdf

    Wer nur denkt, das wäre "Auch Meyers wettert nun gegen endl", sollte bis zum Ende lesen. Oder gleich zur Nachdiskussion springen. Ich war ebenso überrascht wie Herr Meyers, als ich über unitbuf und die Standardvorgaben für den cout-Buffer gelesen habe (bei letzterem meine ich, dass mir das früher schon einmal begegnete, aber ich habe es als Verständnisfehler meinerseits abgetan, weil ich es nicht glauben konnte).

    P.S.: cout beim GCC hat unitbuf nicht gesetzt.


Anmelden zum Antworten