addiert nicht



  • habe gerade mit c++ begonnen und ein vorprogramm zu einem Spaßwahrscheinlichkeitsrechner (statistik).
    (kann sein, dass es unübersichtlich ist)

    mein Problem: b kann eifach nicht addiert werden siehe oma
    außerdem, auch fertig ist es wahrscheinlich stark verbesserugswürdig

    es soll berechnen Σ n (8) über k * 0.51^k * 0.49^k
    oder ein Teil davon, halt ein vorprogramm

    #include <iostream>
    #include <ctime>
    #include <cstdlib> 
    #include <conio.h>
    
    using namespace std;
    
    double hoch(double i, int b)
    {
           int expzaehler = 0;
           double ii = i;
           for(;b>1;b--)
        {
                i*=ii;
    
                if(i<1)
                {
                       for(;i<1;)
                       {
                                 i*=10;
                                 expzaehler++;
                       }
                }
        }
        return i;
    };
    
    int hochexp(double i, int b)
    {
        int expzaehler = 0;
           double ii = i;
           for(;b>1;b--)
        {
                i*=ii;
    
                if(i<1)
                {
                       for(;i<1;)
                       {
                                 i*=10;
                                 expzaehler++;
                       }
                }
        }
        return expzaehler;
    };
    
    double Fak (double i)
    {
           int expzaehler = 0;
           double k = i-1;
           for(; k>1; k--)
        {
                i*=k;
                if(i>10)
                {
                        for(;i>10;)
                        {
    
                             i/= 10;
                             expzaehler++;
                        }
                }
        }
        return i;
    };
    
    int expFak (double i)
    {
        int expzaehler = 0;
           double k = i-1;
           for(; k>1; k--)
        {
                i*=k;
                if(i>10)
                {
                        for(;i>10;)
                        {
    
                             i/= 10;
                             expzaehler++;
                        }
                }
        }
        return expzaehler;
    };
    
    int main()
    {
        int n = 8;
        int t = 0;
        double kk = 0.0;
        int expkk = 0;
        double tt = 0.0;
        int exptt = 0;
        double hk = 0.0;
        double hnk = 0.0;
        int exphk, exphnk;
        double a = 0.0;
        double b = 0.0;
        int bb;
        double aa;
        double p = 0.51;
        double q = 0.49;
        double nn = Fak(n);
        int expnn = expFak(n);
        double oma = 0.0;
        for(int k = 0;k<4; k++)
             {
                  cout<<"nn ( die ! von n als zahl = "<<nn<<endl;
                  cout<<"nn`s exponentenzahl: "<<expnn<<endl;
                     t = n - k;
                     cout<<"t = "<<t<<endl;
                     kk = Fak(k);
                     cout<<"kk = "<<kk<<endl;
                     expkk = expFak(k);
                     cout<<"expkk = "<<expkk<<endl;
                     tt = Fak(t);
                     cout<<"tt = "<<tt<<endl;
                     exptt = expFak(t);
                     cout<<"exptt = "<<exptt<<endl;
                     hk = hoch(p,k);
                     cout<<"hk = "<<hk<<endl;
                     hnk = hoch(q,t);
                     cout<<"hnk = "<<hnk<<endl;
                     exphk = hochexp (p,k);
                     cout<<"exphk = "<<exphk<<endl;
                     exphnk = hochexp (q,t);
                     cout<<"exphnk = "<<exphnk<<endl;
                     a = nn/(kk*tt);
                     cout<<"a = "<<a<<endl;
                     aa = expnn-expkk-exptt;
                     cout<<"aa = "<<aa<<endl;
                             b = (a * hk * hnk) ;
                                       oma+=b;        //hier
                                       cout<<"oma = "<<oma<<endl;
    
                     cout<<"b = "<<b<<endl;
                     bb = aa- exphk - exphnk;  //? kann sein, dass 0,51 trotzdem einen exp ergibt
                     cout<<"bb = "<<bb<<endl;
    
             }
             cout<<b<<endl;
             getch();
    }
    


  • Die Addition, so wie du sie notiert hast, ist mit Sicherheit ok. Es liegt eher an deinen Werten. Wenn oma sich nicht verändert, ist b wohl 0.

    EDIT: Setze dir am besten mal mit dem Debugger einen Haltepunkt und schau dir selbst an, welche Werte in den Variablen stehen.


  • Mod

    Man darf Variablen übrigens auch Namen mit mehr als 1-3 Buchstaben geben. Das ist ganz nützlich, wenn man 15 verschiedene im gleichen Kontext hat. Ich empfehle _, __, ___, ____, _____, usw. als Bezeichner, dann ist es gleich viel leserlicher.



  • Das ist, bis auf den ersten, UB.


  • Mod

    314159265358979 schrieb:

    Das ist, bis auf den ersten, UB.

    Der erste auch, wenn es im globalen Namensraum ist. Aber wirklich undefiniert würde ich das nicht nennen. Es kann halt zu Namenskonflikten kommen.



  • rga schrieb:

    es soll berechnen Σ n (8) über k * 0.51^k * 0.49^k

    Bitte was?



  • Michael E. schrieb:

    rga schrieb:

    es soll berechnen Σ n (8) über k * 0.51^k * 0.49^k

    Bitte was?

    http://de.wikipedia.org/wiki/Binomialkoeffizient
    habe hier noch nicht gefunden, wie ich n über k als Formel schreibe.
    Anders auch n! / (k! * (n-k)!
    damit dann weiter mit * p (also 0.51) hoch k * q (also 0.49) hoch (n-k)
    und diese schleife geht von kanfang= 0 bis if(n%2 != 1){ kende= (n/2) -1 }
    und wenn n ungerade ist, dann kende = (n-1) / 2

    es kommen oft massive exponenten raus zB 6660! wird schon mal zu 1,7699 10^22574
    deswegen habe ich nen exponentenzähler eingebaut, der jedesmal wenn eine Fakultät (oder Potenz) über 10 kommt er /10 teilt, solange bis die variable einen Wert unter 10 hat. Leider bekommt man bei Funktionen immer nur einen rückgabewert, deswegen musste ich meine 2 Funktionen (Fakultät und Potenz) verdoppeln einmal mit dem Wert und einmal mit dem Exponenten. Teilt man zahlen werden die Exponenten subtrahiert zB werden aus 4*10hoch^20 / 2*10hoch^10 = 2
    10hoch10.
    Wenn kende erreicht wird und die gewünschte wahrscheinlichkeit noch nicht erreicht ist wird n um 1 erhöht und so weiter.

    Ein Beispiel für so ne Aufgabe:
    Wie viele Spiele muss man spielen damit bei einer Gewinnwahrscheinlichkeit von 51% (also 0.51) die chacne mehr Spiele zu verlieren als zu gewinnen bei unter 5% liegt?

    Die Antwort 6662 Spiele.

    n ist die Spielanzahl
    also Σ (6660 über k) * 0.51^k * 0.49^(6660-k) = 0.0500205074
    (dabei k anfang = 0 und k ende = 3329)

    Σ (6661 über k) * 0.51^k * 0.49^(6661-k) = 0.051284226
    (dabei k anfang = 0 und k ende = 3330)

    Σ (6662 über k) * 0.51^k * 0.49^(6662-k) = 0.0499954186
    (dabei k anfang = 0 und k ende = 3330)

    nun mein Programm, welches ich vorher hatte. (da müssten noch ein paar Fehler drinne sein wo genau weiß ich nicht, deswegen wollte ich es auseinanderbauen und mit kleinen Zahlen testen siehe oben)

    #include <iostream> 
    #include <cstdlib> 
    #include <conio.h>
    #include <math.h>
    
    using namespace std;
    
    double hoch(double i, int b)
    {
           int expzaehler = 0;
           double ii = i;
           for(;b>1;b--)
        {
                i*=ii;
    
                if(i<1)
                {
                       for(;i<1;)
                       {
                                 i*=10;
                                 expzaehler++;
                       }
                }
        }
        return i;
    };
    
    int hochexp(double i, int b)
    {
        int expzaehler = 0;
           double ii = i;
           for(;b>1;b--)
        {
                i*=ii;
    
                if(i<1)
                {
                       for(;i<1;)
                       {
                                 i*=10;
                                 expzaehler++;
                       }
                }
        }
        return expzaehler;
    };
    
    double Fak (double i)
    {
           int expzaehler = 0;
           double k = i-1;
           for(; k>1; k--)
        {
                i*=k;
                if(i>10)
                {
                        for(;i>10;)
                        {
    
                             i/= 10;
                             expzaehler++;
                        }
                }
        }
        return i;
    };
    
    int expFak (double i)
    {
        int expzaehler = 0;
           double k = i-1;
           for(; k>1; k--)
        {
                i*=k;
                if(i>10)
                {
                        for(;i>10;)
                        {
    
                             i/= 10;
                             expzaehler++;
                        }
                }
        }
        return expzaehler;
    };
    
    int main()
    {
        double wahrscheinlichkeit = 1.0;
        double nn = 0.0;
        double kk = 0.0;
        int expnn = 0;
        int expkk=0;
        double hk = 0.0;
        double hnk = 0.0; 
        double tt = 0.0;
        int exptt = 0;
        int exphk = 0;
        int exphnk=0;
        int aa=0;
        int bb=0;
        double a = 0.0;
        double b = 0.0;
        int nspeicher = 0;
        int ende = 0;
        double p = 0.0;
        double q = 0.0;
        cout<< "gebe die gewinnwahrscheinlichkeit ein"<<endl;
        cin >> p;
        cout<<"gebe die verlierwahrscheinlichkeit ein"<<endl;
        cin >>q;
        for( int n = 4; wahrscheinlichkeit>0.05 ; n++)
        {
             b = 0;
             wahrscheinlichkeit = 0.0;
             nspeicher = n;
             nn = Fak(n);
             expnn = expFak(n);
             if(n%2 != 1)
             {
                    ende = n / 2 -1;
    
             }
             if(n%2 == 1)
             {
                    ende = (n-1) / 2;
             }
             for(int k = 1;k<(ende+1); k++)
             {
                     int t = n - k;
                     kk = Fak(k);
                     expkk = expFak(k);
                     tt = Fak(t);
                     exptt = expFak(t);
                     hk = hoch(p,k);
                     hnk = hoch(q,t);
                     exphk = hochexp (p,k);
                     exphnk = hochexp (q,t);
                     a = nn/(kk*tt);
                     aa = expnn-expkk-exptt;
                     b = b+ a * hk * hnk;
                     bb = aa- exphk - exphnk;  //? kann sein, dass 0,51 trotzdem einen exp ergibt
    
             }
                     if(bb>0)
                     {
                             cout<<bb<<"test1"<<endl;
                             for(;bb>0;bb--)
                     {
                                    b*= 10;
                     }
                     }
                     if(bb<0)
                     {
                             cout<<bb<<"test2"<<endl;
                             for(;bb<0;bb++)
                             {
                                            b/=10;
                             }
                             cout<<bb<<endl;
                     }
                     cout<<b<<endl;
                     cout<<"das n ist"<<n<<endl;
                     wahrscheinlichkeit = b;
                     cout<<"die w ist = "<<wahrscheinlichkeit<<endl;
             }
             cout<<"Fakultät von 6660 ="<<Fak(6660)<<"mit dem exponenten"<<expFak(6660)<<endl;
             cout<<"die von 3329 ist= "<<Fak(3329)<<"mit dem exponenten"<<expFak(3329)<<endl;
             cout<<" 0,51hoch3329ist = "<<hoch(p,3329)<<"mit dem exponenten"<<hochexp(p,3329)<<endl;
             cout<<"0,49hoch3331 ist = "<<hoch(q,3331)<<"mit dem exponenten"<<hochexp(q,3331)<<endl;
    
        cout<<"nach "<<nspeicher<<"Spielen beträgt die wahrsch. mehr zu verlieren unter 5%"<<endl;
        getch();
    }
    

    man kann möglicherweise erkennen, dass ich es teilweise umständlicher und länger als nötig gemacht habe, weil ich noch nicht wircklich Erfahrung mit c++ habe. Tipps zu bestimmten Zeilen könnte ich also gut gebrauchen zB wo ich Zeilen einsparen könnte. Vermutlich könnte ich auch math.h benutzen, jetzt hab ich aber schon ohne angefangen und es ist vermutlich auch keine schande seine Rechenoptionen selber zu programmieren.

    lg



  • nochmal erwähnenswert: das erste Programm war eig schon 100% richtig, was die Ergebnisse belangt. Manuell gerechnet habe ich das Gleiche raus. Das Problem war schlicht, dass man die einzelnen b nicht addieren konnte (oma).
    (Siehe Summe in meiner Formel oben)



  • Bei all den verwirrenden Variablennamen kann ich unmöglich den Fehler finden, geschweige denn zu verstehen, was da genau passiert. Als Erstes solltest du deine Variablen irgendwie sinnvoller benennen. Schau mal, auf welche du verzichten könntest, und schmeiß sie raus. Deklariere die Variablen kurz vor dem Gebrauch (musst natürlich den Sichtbarkeitsbereich beachten) - das wird einige Zeilen einsparen. Rücke bitte den Code ordentlich ein (normalerweise kann man das mit jedem anständigen Compiler automatisch machen). Dann schauen wir mal weiter.



  • In diesen Größenordnungen benutzt man eher die Normalverteilung als gute Annäherung an die Binomialverteilung. Wenn du dennoch die Binomialverteilung benutzen willst (und ich würde nicht drauf wetten, dass du hierdurch genauere Ergebnisse bekommst), würde ich Fakultäten logarithmisch berechnen, d. h. n * (n-1) * ... * (n-k+1) = exp(log(n) + log(n-1) + ... + log(n-k+1)).



  • Und in cmath gibt es std::pow().


Anmelden zum Antworten