Sauber Klasse?



  • Jester schrieb:

    op+= sollte als Rückgabe ne const& haben, op+ ein const-Objekt. Andere analog.

    Darüber lässt sich streiten. Schließlich sollte man sich ja an den Spruch "Do
    as the ints do" halten und sowas geht ja auch:

    int j=0;
    (j+=2)=3;
    


  • nix da schrieb:

    kingruedi schrieb:

    2. Die Variablen sind in der public Schnitstelle. Auch hier solltest du den Link lesen

    Naja ich wollte es eigentlich konfortabel halten und nicht immer sowas machen:

    float _31 = vector.getX();
    

    Das würde bei einer 4x4 Matrix schon sehr auf die Performance hauen, sofern ich mir das Logisch zusammen wurschtel, vorallem bei Matrizenmulitplikationen. Währe es zu Sachen des "Speeds" nicht logisch das OCP zu "sträken"? Denn ich weis nicht eine get_32() funktion bei einer Matrixklasse fände ich extrem bäh.

    zum void: ich finde das bei Syntaxhighlight schöner und erkennlicher, aber jedem das seine, denkst du das ist ein Starkes Kriterium?

    1. schonmal was von inline gehoert? ein vector.getX() kann genauso schnell sein wie ein vector.x

    2. void foo(void) ist C, und in C++ ist dafuer ausdruecklich void foo() vorgesehen.



  • Blue-Tiger schrieb:

    2. void foo(void) ist C, und in C++ ist dafuer ausdruecklich void foo() vorgesehen.

    Wo steht denn das geschrieben? 😕



  • Jester
    Hab noch eine frage zu den Operatoren:

    inline const bool operator == (const vector &vec1, const vector &vec2)
    {
        for (int i=0; i<4; ++i)
        {
            if (vec1.values[i] != vec2.values[i])
                return (false);
        }
        return (true);
    }
    
    inline const bool operator != (const vector &vec1, const vector &vec2)
    {
        return (!(vec1==vec2));
    }
    

    So habe ich die beiden Operatoren != und == implementiert, ich hoffe so ist richtig 😃

    Nur bei dem Operator = weis ich nicht weiter. Den muss man aber wie die x= Operatoren IN die klasse stopfen, weil intern elemente verändert werden, gell?



  • @nix da
    wenn ich mich recht erinner kannst du dir den operator!= sparen da der schon als template version in der STL ist.



  • Mal ne frage, wenn ich sowas schreibe:

    inline const vector operator + (const vector &left, const vector &right)
    {
        return (vector(left.getX()+right.getX(), left.getY()+right.getY(), left.getZ()+right.getZ()));
    }
    
    //und will nun folgendes tun:
    int main (void)
    {
        vector vec1 (3,2,1);
        vector vec2 (1,2,3);;
    
        loki::vector x = vec1+vec2;
    }
    

    Bekomme ich diesen Fehler:
    error C2593: 'operator +' is ambiguous

    Wieso, was habe ich falsch gemacht?? 😕



  • denkt euch das loki:: weg, war ein flüchtigkeitsfehler beim schreiben. alles im globalen namespace



  • fehler kommt aber trotzdem noch 😞



  • Geb ich auch noch meinen Senf dazu...

    1) Kritisch:
    Mathemsatisch falsche Implementation von * (hier erwartet man das Skalarprodukt), und das "sinnlose" operator/(). Zeigt, daß du wenig Erfahrung mit Vektorrechnung hast. Schlecht wenn du dich als Programmierer bei einer 3D-Speileschmiede bewerben willst.

    Mangelhafte Dokumentation. was ist w?

    Verwendung einer platformspezifischen Assembler-Implementation ohne eine Entsprechende portable variante.

    2) Verwirrend
    Dieses this. Ich hab schlimmeres gesehen, aber man fragt sich schon...

    3) Dein Anliegen
    Was willst du mit dem Code zeigen?
    Eine vector-Klasse ist nix wirklich ungewöhnliches, und eher eine Fleißarbeit. Außerdem kann man da jederzeit eine abschreiben. Ich würd' mal kurz drüberlesen ob mir was auffällt (und wenn du Glück den operator* - Lapsus übersehen)

    Hier wären höchstens die Gründe für deine Design-Entscheidungen interessant (Member zugänglich für Komfort? Oder ist Kapselung wichtig/sinnvoll? wie werden plattformspezifische Optimierungen unterstützt?)

    Wenn du ein ineressantes problem elegant löst, wäre das nett. Prinzipiell erwarte ich aber gar keinen Code bei den Bewerbungsunterlagen oder im Anschreiben.



  • @ ***: du kannst gern eine neue Frage aufmachen...

    (ganz IMHO - hier würd' ich mich von einem Kandidaten auch vom Gegenteil überzeugen lassen 😉 )
    Kapselung:
    Wie weit man eine Klasse kapselt ist m.E. eine Design-Entscheidung, die man natürlich vertreten können muß.

    vector ist in den meisten Anwendungsfällen so kritisch, daß man sehr starke Performance-Garantien geben muß - hier genügt nicht mal "amortized constant time", sondern wirklich: ist X ist ein Member, und float.
    Welche Implementationsalternativen existieren denn? anderer Datentyp -> muß man nach außen sehen. Polarkoordinaten? killen jegliche Performance-Garantie.

    In diesem Sinn sind public - Member in diesem Fall nicht nur Komfort (insbesondere beim Lesen von Komplexeren Vektorarithmetik-Ausdrücken), sondern auch Performance-Garantie.



  • Warum ist die Klasse nicht generisch implementiert? Willst du das gleiche für int, double usw. nochmal schreiben?



  • Gregor schrieb:

    Warum ist die Klasse nicht generisch implementiert? Willst du das gleiche für int, double usw. nochmal schreiben?

    Float reicht doch (deckt ja int mit ab).



  • interpreter schrieb:

    Float reicht doch (deckt ja int mit ab).

    Nein.



  • Gregor schrieb:

    interpreter schrieb:

    Float reicht doch (deckt ja int mit ab).

    Nein.

    Tolle Antwort. Begründung?



  • interpreter schrieb:

    Tolle Antwort. Begründung?

    Probier es aus:

    #include <iostream>
    
    int main ()
    {
       int a = 2000000100;
       std::cout << a << std::endl;
       float b = (float) a;
       int c = (int) b;
       std::cout << c << std::endl;
    }
    

    Output:

    2000000100
    2000000128
    

    Es geht also etwas bei der Umwandlung verloren. Das ist auch nicht verwunderlich. Wenn man annimmt, dass in diesem speziellen Fall ein int 32 Bit hat und ein float auch, dann kann ein float nicht die Genauigkeit von int bieten, weil hier 8 Bit für den Exponenten draufgehen.

    Abgesehen davon wird eine generische Implementierung aus Performance-Gründen besser sein. Ich gehe einfach mal davon aus, dass Ganzzahlarithmetik schneller als Fließkommaarithmetik ist. ...und was ist mit einem Vektor für double, für eine Bruchklasse, usw.?



  • vector vector::crossProduct (const vector &other) 
    { 
        vector result; 
    
        __asm 
        { 
            mov esi, this 
            mov edi, other 
    
            movups xmm0, [esi] 
            movups xmm1, [edi] 
            movaps xmm2, xmm0 
            movaps xmm3, xmm1 
    
            shufps xmm0, xmm0, 0xC9 
            shufps xmm1, xmm1, 0xD2 
            mulps  xmm0, xmm1 
    
            shufps xmm2, xmm2, 0xD2 
            shufps xmm3, xmm3, 0xC9 
            mulps  xmm2, xmm3 
    
            subps  xmm0, xmm2 
    
            mov    esi, result 
            movups [esi], xmm0 
        } 
    
        w = 1.0f; 
    
        return (result); 
    }
    

    ich wette mit dir, dass der compiler einen mindestens genausoschnellen code erzeugt!



  • du weist das die SSE wurzel schneller errechnet wird als die aus der stdlib, gell?



  • nix da schrieb:

    du weist das die SSE wurzel schneller errechnet wird als die aus der stdlib, gell?

    Das ist eine 100% Library abhängige Behauptung.



  • nix da schrieb:

    du weist das die SSE wurzel schneller errechnet wird als die aus der stdlib, gell?

    und warum sollte die Library die Wurzel nicht mit SSE ziehen können?



  • kingruedi schrieb:

    nix da schrieb:

    du weist das die SSE wurzel schneller errechnet wird als die aus der stdlib, gell?

    und warum sollte die Library die Wurzel nicht mit SSE ziehen können?

    weil es drauf ankommt ob die runtime lib von dem OS auch SIMD-Technologie eingebunden ist, und bei 2000 und XP ist dem nicht so. Macht doch mal nen Profilertest


Anmelden zum Antworten