metaprogrammierung: euklidischer algorithmus



  • also, ich hab mir ne struct zum thema euklidischer algorithmus und ggt geschrieben, und das macht mir atm nur probleme:

    template<int N,int Z> struct Ggt<var<N,Z> >{
    	private:
            //gt berechnen
    		enum{Calc=N%Z?Ggt<var<Z,N%Z> >::Value:Z};
    	public:
            //testen ob N<Z
    		enum{Value=N<Z?Ggt<var<Z,N> >::Value:Calc};
    };
    //division durch 0 verhindern
    template<int N> struct Ggt<var<N,0> >{
    	enum{Value=1};
    };
    

    ja, ich weis, sieht etwas komisch aus, aber rein theoretisch sollte es klappen.
    das problem ist nur, dass mir der compiler sagt:

    Value is not a member of type hidden::Ggt<var<2, 2> >
    

    ich sitz da jetzt schon ne halbe stunde vorm problem, scheine aber den wald vor lauter bäumen nicht zu sehen :(,bzw mir ist nicht klar, wieso er Value nicht kennt



  • (du könntest den ganzen templatewirrwarr wegmachen, und eine normales klassentemplate mit memberfunktionen machen, dann stellt sich das problem vermutlich nicht)



  • Korbinian schrieb:

    (du könntest den ganzen templatewirrwarr wegmachen, und eine normales klassentemplate mit memberfunktionen machen, dann stellt sich das problem vermutlich nicht)

    (imho krieg ich dann probleme, wenn ich eine komplette logaithmentabelle oder andere komplexere sachen zur compilezeit berechnen will)



  • otze schrieb:

    komplette logaithmentabelle oder andere komplexere sachen zur compilezeit berechnen will

    wozu? designproblem?



  • geschwindigkeitsproblem, der algorithmus ist teuer,genauso wie sinus/cosinus/tangens/wurzeln...
    wenn ich sowas in die compilezeit auslagern kann, finde ichs toll 😉



  • warum machste dann keine lookuptabellen oder ähnliches? sin/cos etc ist ausserdem schon optimiert. naja, aber musst selber wissen, ich bin noch nie in die situation gekommen, sowas zu brauchen 🙂



  • warum machste dann keine lookuptabellen oder ähnliches

    mach ich doch 🙂



  • Darf man mal fragen: Was ist var?

    mfg
    v R



  • ich als ewiger C++ Anfänger hätt mal kurz eine Frage ;), warum macht man eigentlich solche Spielerein mit enum? otze erklär mal ein wenig bitte 🙂

    bye

    tt



  • virtuell Realisticer schrieb:

    Darf man mal fragen: Was ist var?

    mfg
    v R

    template<int N,int Z>
    struct var{
        typedef var<N,Z> Value;
    };
    

    @Thetester die kurze oder die lange version?^^



  • Hier mal ohne enums:

    template<int N,int Z> struct ggt { 
             static const int Value =  ggt<Z, N % Z>::Value; 
    };
    
    template<int N> struct ggt< N, 0> { 
         static const int Value = N; 
    };
    
    template<int N,int Z> struct Ggt { 
             static const int Value =  (N>Z) ?  ggt<Z, N % Z>::Value : ggt< Z,N >::Value; 
    };
    


  • Oder einfacher:

    template<int N,int Z> struct Ggt { 
         public: 
             static const int Value =  Ggt<Z, N % Z>::Value; 
    };
    
    template<int N> struct Ggt< N, 0>
    { 
    public:
         static const int Value = N; 
    };
    


  • Ponto schrieb:

    Hier mal ohne enums:

    template<int N,int Z> struct ggt { 
             static const int Value =  ggt<Z, N % Z>::Value; 
    };
    
    template<int N> struct ggt< N, 0> { 
         static const int Value = N; 
    };
    
    template<int N,int Z> struct Ggt { 
             static const int Value =  (N>Z) ?  ggt<Z, N % Z>::Value : ggt< Z,N >::Value; 
    };
    

    auch wenn ichs nur überflogen hab:
    zwischen struct 1 und 3 besteht eine unauflösbarkeit für den compiler und das 2. ist vom sinn falsch ;).

    //zu deinem edit

    template<int N,int Z> struct Ggt {
         public:
             static const int Value =  Ggt<Z, N % Z>::Value;
    };
    

    nun ist sogar der algorithmus ansich falsch^^

    //edit2 oops der erste algo ist ja auch falsch^^



  • otze schrieb:

    auch wenn ichs nur überflogen hab:
    zwischen struct 1 und 3 besteht eine unauflösbarkeit für den compiler und das 2. ist vom sinn falsch ;).

    //zu deinem edit

    template<int N,int Z> struct Ggt {
         public:
             static const int Value =  Ggt<Z, N % Z>::Value;
    };
    

    nun ist sogar der algorithmus ansich falsch^^

    Du solltest es lieber ausprobieren, bevor du meckerst. Hier ist das gleiche mit enums:

    template<int N,int Z> struct Ggt { 
         public: 
             enum {Value =  Ggt<Z, N % Z>::Value}; 
    };
    
    template<int N> struct Ggt< N, 0>
    { 
    public:
         enum {Value = N}; 
    };
    


  • @otze: Warum brauchst du das var? Welchen Vorteil bringt es dir?

    Der noch nicht so fitte Metaprogrammierer
    v R 😉



  • static const int Value =  Ggt<Z, N % Z>::Value
    

    du weisst, das dies nur möglich sit, wenn z größer n ist? und das man sonst ein falsches ergebnis rausbekommt?
    die enums ändern daran auch nichts.

    Value = N

    darf auch nicht sein, wenn der zähler null ist.

    @VR aus dem grund:
    typedef Mul<var<1,2>,var<3,4> mul;
    typedef Add<mul,var<5,6> > add

    wenn ich das jetzt mit ints anstatt var machen wollte, sähe das so aus:
    typedef Mul<1,2,3,4> mul;
    typedef Add<mul::N,mul::Z,5,6 > add;

    je komplexer die ausdrücke sind, desto unschöner wird der weg über ints, da man im ersten fall direkt ausnutzen kann, dass man ein template<class> stehen hat, die möglichkeit ist einem beim 2. nicht gegeben.



  • otze schrieb:

    static const int Value =  Ggt<Z, N % Z>::Value
    

    du weisst, das dies nur möglich sit, wenn z größer n ist? und das man sonst ein falsches ergebnis rausbekommt?
    die enums ändern daran auch nichts.

    Value = N

    darf auch nicht sein, wenn der zähler null ist.

    Du hast es einfach nicht ausprobiert. Aber hier ein paar Fragen, damit es Klick macht:

    Was ist 3 % 15 ?
    Was ist 15 % 3 ?

    Bei N = 15, Z = 3. Was wird Z, N % Z ?
    Bei N = 3, Z = 15. Was wird Z, N % Z ?



  • Vielleicht kann man sich ja hier noch ein wenig abgucken...



  • Was ist 3 % 15 ?//3
    Was ist 15 % 3 ? //0

    //edit ok ponto, hast gewonnen, habs nochmal getestet, kommt der richtige wert raus, sorry, dass ich dich etwas geflamed hab, asche auf mein haupt.
    wenn du willst, kriegste ne kleine Danksagung an der Stelle im Code 😉



  • ok nachdem ponto gezeigt hat das es auch ohne enum geht, was ich leichter verständlich finde...warum macht man das dann noch mit enum? bringt das noch irgendwas? vergewaltigt ihr das nur damit ihr euch "variablen" spart? ist sowas eigentlich gängige praxis?

    bye

    tt



  • TheTester schrieb:

    ist sowas eigentlich gängige praxis?

    andrei alexandrescou machts so,ich habs mir von ihm die basics abgeschaut, und dann weitergemacht 😃

    wahrscheinlich wirds benutzt, da die enum ein eigener typ ist, und somit gegebenenfalls schneller sein kann, aber nichts genaues weis ich nicht^^


Anmelden zum Antworten