Funktionenproblem



  • Hi Leute!

    Ich soll folgende Aufgabe erledigen:

    Schreiben Sie eine Funktion armstrong(n), die 1 zurückliefert, wenn die Ganzzahl n
    eine Armstrong-Zahl ist. Sonst wird 0 zurückgegeben. Erweitern Sie dazu auch Ihre
    Funktion kubik, so dass sie zur Berechnung beliebiger Armstrong-Zahlen größer als
    Null verwendet werden kann. Testen Sie die Funktion armstrong im Hauptprogramm
    durch Ausgabe aller Armstrong-Zahlen zwischen 1 und 10000.

    Ich hab mir dazu jetzt schon mal eine Schleife gebaut, die mir den Exponenten berechnet, dieser ist ja Abhängig von der Stellenanzahl der eingegebenen Zahl. Jetzt muss ich ja in Abhängigkeit des Exponenten die jeweiligen Stellen der Zahl so oft mit sich selbst multiplizieren wie es der Exponent vor gibt.

    So, soweit so gut... Ab da hakts aber. Könnt ihr mir helfen?

    der Coder der while schleife

    unsigned int n, exp, x, a;
    
        cin >> n;
    
        exp = 0;
        while(n > 0)
        {
         n = n / 10;
         exp = exp + 1;
        } 
        cout << exp << endl;
    


  • Aufgabenstellung: Schreiben sie eine Funktion ... ! Erster Schritt: Funktionssignatur angeben!


  • Mod

    Ist deine Schwierigkeit, die Stellen der Zahl zu bestimmen?

    Die hinterste Stelle einer Zahl i zur Basis b ist i[0] = (i / (b hoch 0)) % b. Die nächste Stelle ist i[1] = (i / (b hoch 1)) % b. Die n-te Stelle ist i[n] = (i / (b hoch n)) % b.

    Hoffentlich habe ich mich gerade nicht verrechnet, probiers lieber erstmal an einem Beispiel aus 🙂 .

    P.S.: Mit / ist natürlich die Ganzzahldivision gemeint.



  • und wie setze ich das jetzt in programmcode um? ich kann ja nicht einfach hoch schreiben und außerdem variiert ja die Zahl der hochs auch noch...



  • Okay, ich nehm's raus.

    Edit: Wenn knivil wild editiert, kann ich's auch:

    4[h]5[/h] + 1[h]5[/h] + 5[h]5[/h] + 0[h]5[/h]
    1024 + 1 + 3125 + 0 = 4150 , 4151 eben 4150+1[h]5[/h]
    


  • @Vicious Falcon: Na toll, und was hat er gelernt? Nichts! Die naechsten par Beitraege wird es nur darum gehen, deine Implementation zu verstehen. Diese ist wahrscheinlich nicht mal die beste, da mit Fliesskommazahlen gerechnet wird. Sie ist auch fehlerhaft, da 4150 und 4151 auch ausgegeben werden.



  • Ich verstehe das obere nicht, wills auch so nicht machen und nicht durcgehen.


  • Mod

    knivil schrieb:

    da mit Fliesskommazahlen gerechnet wird.

    Ach, bevor man extra eine eigene Potenzfunktion schreibt ist das doch in Ordnung. Bis 2^53 rechnet man bei double und Ganzzahlen exakt.



  • bandchef schrieb:

    Ich verstehe das obere nicht, wills auch so nicht machen und nicht durcgehen.

    Gut, wie sieht deine Funktionssignatur aus? Welche Funktionen brauchst du noch und wie sehen die Signaturen aus?

    SeppJ schrieb:

    Bis 2^53 rechnet man bei double und Ganzzahlen exakt.

    Da normalerweise die Potenzen ueber die e-Funktions implementiert sind, koennen Ungenauigkeiten schon frueher auftreten. Genau weiss ich es aber nicht.



  • Mein Code sieth jetzt so aus:

    #include<iostream>
    using namespace std;
    
    //Funktionendeklaration
    
    int potenz(unsigned int x)
    {
        unsigned int a, exp;
    
    	a = 1;
    
        while(exp > 0)
        {
         a = a * x;
         exp = exp - 1;
        }
    
        return a;
    }
    
    int main()
    {
        unsigned int n, exp, x, y, z, a;
    
        cin >> n;                           //Eingabe Zahl
        a = n;
    
        exp = 0;                            //Berechnung der Potenz anhand der Zahl
        while(n > 0)
        {
         n = n / 10;
         exp = exp + 1;
        }
    
        cout << exp << endl;
    
        while(exp > 0)                         //Berechnung der Zahl mit Funktion
        {
         y = (n / potenz(10)) % 10;
         exp = exp - 1;
        }
    
        cout << y << endl;
    
    system("pause");
    return 0;
    }
    

    Das Problem besteht jetzt an der letzten while-Schleife in der main. Ich will hier jetzt quasi jede einzelne Stelle zerlegt mit der gleichen Potenz (bei einer 4-stelligen Zahl ist die potenz jeder Ziffer auch 4) miteinander addieren. Versteht ihr was ich meine?


  • Mod

    knivil schrieb:

    SeppJ schrieb:

    Bis 2^53 rechnet man bei double und Ganzzahlen exakt.

    Da normalerweise die Potenzen ueber die e-Funktions implementiert sind, koennen Ungenauigkeiten schon frueher auftreten. Genau weiss ich es aber nicht.

    Guter Einwand. Probieren wir es aus:

    #include<cmath> 
    #include<iostream>
    #include <stdint.h>
    using namespace std;
    
    uint64_t pow(uint64_t base, unsigned exponent)
    {
      uint64_t result=1;
      for (unsigned i=0; i<exponent; ++i) result*=base;
      return result;
    }
    
    int main()
    {
      for(uint64_t base=1; base<pow(2,52); ++base)
        {
          unsigned max_exp=log(pow(2,53))/log(base);
          for (unsigned exponent=1; exponent< max_exp; ++exponent)
            {
              double floatingpow = pow(static_cast<double>(base), static_cast<double>(exponent));
              if (floatingpow > pow(2., 53.)) break; // Überlauf
              uint64_t integerpow = pow(base, exponent);
              if (floatingpow!=integerpow)
                {
                  cout<<"Ungenaues Ergebnis: "<<base<<" hoch "<<exponent << " = " << integerpow << " != " << floatingpow <<'\n';
                }
          }
        }
    }
    

    Wird ein bisschen brauchen, alle Kombinationen durchzuprobieren, aber bei mir läuft das Programm nun schon sehr sehr lange ohne eine Fehlstelle zu finden.



  • Ich glaub ich hab mein Problem etwas umständlich formuliert. Für die Zahl 325 soll die letzt while-Schleife folgendes machen: 33+23+5^3. Nur eben jetzt nicht nur für diese Zahl bzw. nicht nur für Zahlen mit 3 Stellen sondern von 1 bis unendlich viele Stellen! Ich glaub so ist es verständlicher



  • Einfaches Schema:

    Zahl = 123
    letzte zahl = 0

    1. letze Zahl = Zahl Modulo 10

    letzte Zahl = 3

    2. Zahl = Zahl - letzte Zahl
    3. Zahl = Zahl / 10

    Zahl = 12


  • Mod

    bandchef schrieb:

    Ich glaub ich hab mein Problem etwas umständlich formuliert. Für die Zahl 325 soll die letzt while-Schleife folgendes machen: 33+23+5^3. Nur eben jetzt nicht nur für diese Zahl bzw. nicht nur für Zahlen mit 3 Stellen sondern von 1 bis unendlich viele Stellen! Ich glaub so ist es verständlicher

    Und wo ist dein Problem? Wie du die Stellen einer Zahl bestimmen kannst, wurde dir schon erklärt und (wenn du Vicious Falcons Komplettlösung nicht einfach mit "Bäh, mag nicht nachdenken" abgelehnt hättest) sogar explizit vorgemacht.



  • int potenz(unsigned int x)
    

    Du moechtest also x^exp rechnen? Diese Funktion muss 2 Parameter haben, x und der entsprechende Exponent. Auch ist in der Funktion a und exp nicht initialisiert. Wenn du das hast, dann implementiere die Funktion potenz .

    Als zweites wuerde ich eine Funktion fuer die Anzahl der Ziffern schreiben. Nach http://de.wikipedia.org/wiki/Narzisstische_Zahl muss jeder Ziffer hoch ihrer Laenge in der Summe wieder die gleiche Zahl ergeben.

    Wird ein bisschen brauchen, alle Kombinationen durchzuprobieren

    Ich haette binaere Suche verwendet ... Alle Zahlen bis 2^53 durchzuprobieren bei 1GHz dauert wohl 9007199s bzw. 2501 Stunden.



  • Sorry, aber ich kapiers einfach nicht. Es geht ja jetzt nur noch darum die eingegebene Zahl in ihre einzelnen Stellen zu zerlegen und mit dem jeweiligen Exponenten zu potenzieren und danach sämtlich stellen zu addieren. Könnt ihr mir nicht nochmal speziell dazu helfen?



  • knivil schrieb:

    ..fehlerhaft, da 4150 und 4151 auch ausgegeben werden.

    4[h]5[/h] + 1[h]5[/h] + 5[h]5[/h] + 0[h]5[/h]
    1024 + 1 + 3125 + 0 = 4150 , 4051 eben 4150+1[h]5[/h]
    

    War ein Zufall, dass ich deinen Edit gerade noch gesehen habe.



  • Wenn er eine eigene Lösung entwickeln möchte ist das nur nachvollziehbar. Trotzdem würde ich gerne an V.Falcons appellieren seine schöne Lösung wieder in den Post aufzunehmen, da dies für eventuell zukünftige Leser hilfreich sein wird.

    Momentan möchte der Autor aber nur wissen wie man auf eine für ihn verständliche Weise eine Zahl in seine Bestandteile zerlegen kann.



  • Fuer 4150 ist n = 4 bei mir. Und sie taucht beispielsweise nicht in der Tabelle bei Wikipedia auf.

    appellieren seine schöne Lösung wieder in den Post aufzunehmen

    Gern, wenn sie er nicht mehr hat, ich habe sie noch. 🙂



  • ch hab sie nicht.


Log in to reply