metaprogrammierung: euklidischer algorithmus



  • 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^^



  • Könnte das nicht der gute alte "enum-Hack" sein?

    This is a workaround for compilers which do not support the standard C++ feature of initialization of static constants inside the class definition.

    http://home.earthlink.net/~joshwalker1/writing/TemplateMetaprogramming.html

    Oder gibt es andere Gründe? 😕



  • dann wirds das sein 🙂



  • ah cooler link, jetzt versteh ich den Nutzen davon besser 🙂



  • achja, der artikel hat meine letzte aussage doch verstärkt(steht ganz unten in den notes)

    Additionally, curiously enough, the enum version compiles over twice as fast as the static const int version on gcc 2.95.3.



  • otze schrieb:

    achja, der artikel hat meine letzte aussage doch verstärkt(steht ganz unten in den notes)

    Additionally, curiously enough, the enum version compiles over twice as fast as the static const int version on gcc 2.95.3.

    Naja, damit deine Aussage verstaerkt wird, muesste man wissen, wie es auf
    aktuellen Compilern aussieht, imho.

    mfg
    v R



  • @otze
    Dein Versuch in Ehren, aber wenn du damit 'ne Art LUT machen willst, dann ist TMP imo etwas übertrieben. Da sowas eh am Anfang des Programmes einmalig ausgeführt wird, spielt Geschwindigkeit dabei nur eine untergeordnete Rolle.



  • LUT? TMP? was heisst das? danach kann man so schwer googlen^^

    //edit lut=lookuptable?



  • @otze: Kann es sein, daß Du auf den guten alten ?: Trick reingefallen bist?
    Im Gegensatz zur Laufzeit wird zur Compilezeit kein short-curcuit evaluation betrieben und nicht nur der Code kompiliert, der im jeweils relevanten Teil steckt, sondern auch der andere Teil wird instanziiert.



  • @otze:
    LUT - Look Up Table
    TMP - Template Meta Programming


Anmelden zum Antworten