Potenzierung funzt net -.-



  • moin

    die Potenzierung funktioniert leider nicht,trotz richtiger Programmierung:

    int main()
    {
    	int n = 2, x = 5, anzahl = 0;
    	while(anzahl < n)
    	x *= x;
    	std::cout<<x;
    	return 0;
    }
    

    Wo könnte der Hacken liegen?
    Es kommt nähmlich kein Ergebnis,nichtmal "0" 😞

    Mrnull



  • edit: habs nun selber rausbekommen

    Kann gelöscht werden 😉



  • ganz ehrlich? Das ist ne Endlosschleife ^^



  • aber keine Schlechte! 😉
    ... ich würd ne for - Schleife empfehlen! 🙂



  • // berechnet x^n
    int exp (int x, unsigned int n) 
    {
       int y = 1; 
    
       while (n) 
       {
          if (n & 1) 
              y = x*y;
          n >>= 1; 
          x *= x;    
       }
       return y;
    }
    

    🙂



  • Oh, ich hab auch noch eine, aber nur für Integer:

    inline int pow(int base, int exp) {
      int z = 1;
      while (exp > 0) {
        while (exp%2 == 0) {
          exp /= 2;
          base *= base;
        }
        --exp;
        z *= base;
      }
      return z;
    }
    


  • life_drake schrieb:

    aber keine Schlechte! 😉
    ... ich würd ne for - Schleife empfehlen! 🙂

    Oder, wie in einem anderen Thread gerade angesprochen, eine Rekursion.



  • Konrad Rudolph schrieb:

    life_drake schrieb:

    aber keine Schlechte! 😉
    ... ich würd ne for - Schleife empfehlen! 🙂

    Oder, wie in einem anderen Thread gerade angesprochen, eine Rekursion.

    Ehm ne, die ist nicht zu empfehlen. Erst recht nicht in der Variante, die lineare Rekursionstiefe hat.



  • Konrad Rudolph schrieb:

    life_drake schrieb:

    aber keine Schlechte! 😉
    ... ich würd ne for - Schleife empfehlen! 🙂

    Oder, wie in einem anderen Thread gerade angesprochen, eine Rekursion.

    was gefällt euch nicht an GPC's und meinem code?



  • pale dog schrieb:

    Konrad Rudolph schrieb:

    Oder, wie in einem anderen Thread gerade angesprochen, eine Rekursion.

    was gefällt euch nicht an GPC's und meinem code?

    Dass er nicht rekursiv ist. Also, eure Codes sind natürlich super aber ich denke lieber rekursiv als iterativ, weil ich das intuitiver finde. Außerdem lässt sich euer Algorithmus 1:1 in eine Rekursion übertragen:

    unsigned int pow_test(unsigned int base, unsigned int exp, unsigned int accu = 1) {
        if (exp == 0)
            return accu;
        else if (exp % 2 == 0)
            return pow_test(base * base, exp / 2, accu);
        else
            return pow_test(base, exp - 1, accu * base);
    }
    

    Mit eingeschalteter Optimierung dürften all diese Codes relativ gleiche Leistungen bringen.



  • Konrad Rudolph schrieb:

    Dass er nicht rekursiv ist.

    rekursion sieht zwar nett aus, hat zur laufzeit aber nur nachteile.
    übrigens, deine funktion kommt nicht mit negativen zahlen klar 😉



  • pale dog schrieb:

    rekursion sieht zwar nett aus, hat zur laufzeit aber nur nachteile.

    Nönö. Deswegen ist meine Funktion ja endrekusiv implementiert. Wie gesagt: Ich denke, dass die Performance meines Codes in etwa mit der eurer Codes übereinstimmen sollte. Ein guter Compiler *könnte* das zumindest hinbekommen, für alle drei Codes dieselbe Ausgabe zu erzeugen. Von VC 8 weiß ich definitiv, dass Endrekursion weg-optimiert wird. Der aktuelle GCC kann es angeblich auch. Wenn der Compiler dann noch merkt, dass er keine Werte hin und her kopieren muss sondern die Register direkt überschreiben kann, dann ist doch alles in Butter.

    Sowas zu optimieren ist übrigens IMHO eine *typische* Aufgabe des Compilers und eben nicht des Programmierers.

    übrigens, deine funktion kommt nicht mit negativen zahlen klar 😉

    Ja, weil ich die Parameter 'unsigned' gemacht habe. 'base' könnte natürlich auch ein Vorzeichen tragen, würde auch klappen:

    int pow(int base, unsigned int exp, int accu = 1) {
        if (exp == 0)
            return accu;
        else if (exp % 2 == 0)
            return pow(base * base, exp / 2, accu);
        else
            return pow(base, exp - 1, accu * base);
    }
    

    Mit negativen Exponenten kommt Dein Code ja auch nicht klar.



  • Konrad Rudolph schrieb:

    Sowas zu optimieren ist übrigens IMHO eine *typische* Aufgabe des Compilers und eben nicht des Programmierers.

    sich eben nicht auf besonders ausgefeilte optimierungsmöglichkeiten des compilers zu verlassen, ist die aufgabe des programmierers 😉



  • Rekursiv ist intuitiv ?
    Na, so eine Intuition hätte ich auch gern. Meine ist da einfacher:

    long potenzieren( int basis, int exponent )
    {
    	int i = 0; long ergebnis = basis;
    
    	if ( ! exponent ) return 1;
    
    	for ( i = 0; i<exponent -1; i++ )
    	{
    	  ergebnis =   ergebnis * basis;
    	}
    
    	return ergebnis;
    }
    

    Das dürfte damit auch gleichzeitig die schnellste Version sein ( nur Multiplikation ) 😃
    Warum müsst ihr euren Quellcode so quetschen, findet ihr das schön ?



  • tststs schrieb:

    Das dürfte damit auch gleichzeitig die schnellste Version sein

    nö, meine ist schneller...
    im schnitt mehr als doppelt so schnell
    🙂



  • tststs schrieb:

    Rekursiv ist intuitiv ?
    Na, so eine Intuition hätte ich auch gern.

    Dann eigne sie Dir doch an. Ist alles ne Sache der Gewöhnung.

    Warum müsst ihr euren Quellcode so quetschen, findet ihr das schön ?

    Das ist 'n Witz, oder? Was ist denn an meinem Quellcode z.B. gequetscht? Ich habe vor und nach jedem Rechenzeichen ein Leerzeichen und füge wo nötig neue Zeilen ein. Dein Code hingegen scheint keinerlei System zu haben und streut willkürlich Leerzeichen ein (oder lässt sie weg). Und neue Zeilen scheinen auch nur eine Randexistenz zu führen (siehe Deine Deklarationen).



  • Tatsache, pale dog, deine ist schneller.
    Bei mir es es ein Faktor von 1,3. Deine ist also 1,3 mal schneller,
    aufgerundet zu deinen Gunsten 😃
    Ich habe gelesen, das Bitshift langsamer als Multiplikation ist, darum war ich mir meiner Sache so sicher, naja, Pech 😃

    Meine willkürlichen Leerzeichen dienen der Auflockerung zwecks Leserlichkeit.



  • tststs schrieb:

    Tatsache, pale dog, deine ist schneller.
    Bei mir es es ein Faktor von 1,3. Deine ist also 1,3 mal schneller

    Nö. Der Code ist nicht um einen konstanten Faktor schneller sondern wesentlich schneller. Dein Code hat eine lineare Laufzeit, der Code von pale dog hingegen eine logarithmische, d.h. je größer die zu berechnende Zahl wird, desto größer wird der Abstand zwischen den beiden Codes.

    Meine willkürlichen Leerzeichen dienen der Auflockerung zwecks Leserlichkeit.

    Interessante Auffassung.



  • Logarithmische Laufzeit, sowas kompliziertes hat der da gebaut, das hab ich gar nicht bemerkt.

    Der Faktor 1,3 bezog sich auf die Basis 5 und den Exponenten 7, da bin ich gar nicht auf die Idee gekommen, das das so eine Tricky Funktion ist, wo lernt man sowas ?
    🙂



  • tststs schrieb:

    Tatsache, pale dog, deine ist schneller.
    Bei mir es es ein Faktor von 1,3. Deine ist also 1,3 mal schneller,
    aufgerundet zu deinen Gunsten 😃

    dann setz mal bei beiden grössere exponenten ein 😉

    tststs schrieb:

    Ich habe gelesen, das Bitshift langsamer als Multiplikation ist, darum war ich mir meiner Sache so sicher, naja, Pech 😃

    shifts sind sowieso schneller als multiplikationen, aber daran liegt's nicht. die anzahl benötigter operationen, für die komplette berechnung, ist bei meiner im durchschnitt viel kleiner.

    tststs schrieb:

    ...das das so eine Tricky Funktion ist, wo lernt man sowas?

    aus büchern 😉
    --> http://www.awprofessional.com/bookstore/product.asp?isbn=0201914654&rl=1


Anmelden zum Antworten