Ergebnis 1 bis 20 von 21

Thema: Wurzle Problem

Hybrid-Darstellung

Vorheriger Beitrag Vorheriger Beitrag   Nächster Beitrag Nächster Beitrag
  1. #1

    Users Awaiting Email Confirmation

    Wurzle Problem

    hallo, ich habe mal wieder ein noob problem:
    ich wollte eigentlich bloß eine Wurzelfunktion erstellen:
    Code:
    #include <iostream>
    
    using namespace std;
    
    int Global=0;
    
    const double PI=3.141592653;
    
    #define BR cout<<'\n';
    
    double Wurzel(int a, double b=0);
    
    int main(void)
    {
       cin>>Global;
       Wurzel(Global);
       BR
       
       cin>>Global;
       return 0;
    }
    double Wurzel(int a, double b)
    {
       while(b*b<a)
       {
          cout<<"b*b ist: "<<b*b;
          BR
          cout<<"a ist : "<<a;
          BR
          if(!(b*b<a))cout<<"b*b ist nicht kleiner als a\n";
          b+=0.001;
          cout<<b;
          BR
       }
       return b;
    }
    Jedoch wenn ich ich im Prog dann 4 eingebe kommt am Ende 2.001 raus, könnte das tzwar umgehen, aber wo liegt der Fehler?

  2. #2
    Wieso benutzt du nicht einfach die eingebaute Wurzel-Funktion? Oder wenigstens einen vernuenftigen Algorithmus, und nicht Bruteforce?

  3. #3

    Users Awaiting Email Confirmation

    wusste zwar nicht das es eine Wurzel Funktiojn ist, aber ich wollte esja eh als Übung machen und was Bruteforce ist weiß ich noch nicht, bin noch Anfänger, aber uhrsprünglich war das Programm so, also ohne die Verschönerung, wenn du das meinst:
    Code:
    #include <iostream>
    
    using namespace std;
    
    int Global=0;
    
    const double PI=3.141592653;
    
    #define BR cout<<'\n';
    
    double Wurzel(int a, double b=0);
    
    int main(void)
    {
       cin>>Global;
       cout<<Wurzel(Global);
       BR
       
       cin>>Global;
       return 0;
    }
    double Wurzel(int a, double b)
    {
       while(b*b<a)
       {
          b+=0.001;
       }
       return b;
    }
    Was da passiert?
    Ich gebe eine 4 ein und als Wurzel bekomme ich 2.001 zurück.
    Das was ich in dem anderem eingegeben habe sollte nur zeigen das bei b*b 4 am Ende rauskommt und a 4ist aber dass b*b kleiner als a scheint, was nach meiner Logik sehr seltsam ist oder?

  4. #4
    Afaik(kenn mich mit Fließkommazahlen nicht aus) liegt das daran, dass du double benutzt, ohne Nachkommastelle wird eine Fließkommazahl iirc in einen Integer umgewandelt.

    Wieso hast du eigentlich b als Parameter? oO

  5. #5

    Users Awaiting Email Confirmation

    Dachte eigentlich auch du hättest recht, aber:
    Code:
    #include <iostream>
    
    using namespace std;
    
    double Global=0;
    
    const double PI=3.141592653;
    
    #define BR cout<<'\n';
    
    double Wurzel(double a, double b=0);
    
    int main(void)
    {
       cin>>Global;
       cout<<Wurzel(Global);
       BR
       
       cin>>Global;
       return 0;
    }
    double Wurzel(double a, double b)
    {
       while(a>b*b)
       {
          b+=0.001;
       }
       return b;
    }
    Anderer Code, gleiches Ergebnis

  6. #6
    Euch ist schon klar, das man so etwas normalerweise über Lookuptables und Interpolieren rechnet, oder?

  7. #7

    Users Awaiting Email Confirmation

    Nun, mir nicht bin aber auch noch Anfänger,aber es ist eh nur eine Übung, bei der ich aber nicht versteh weshalb das falsch läuft!

  8. #8
    Zitat Zitat von Tridestaros Beitrag anzeigen
    Nun, mir nicht bin aber auch noch Anfänger,aber es ist eh nur eine Übung, bei der ich aber nicht versteh weshalb das falsch läuft!
    Okay, ich hab' mich gerade hingesetzt und ein klein wenig gerechnet: Die Quadratwurzel sollte sich über das newtonsche Näherungsverfahren ermitteln lassen. Ich habe das ganze jetzt für den speziellen Fall aufgelöst und bin auf folgende Funktion gekommen:

    x_{n+1} = (x_{n} + z/x_{n})/2

    In dem Fall näherst du dich an die Wurzel von z an, wobei du mit n immer durch iterierst. Soll heißen: Du rechnest dir erst immer x_{0} aus, dann x_{1}, usw. Bis das Ergebnis deiner Meinung nach genau genug ist.


    Warum das nicht verwendet wird, siehst du hier auch recht gut: Das ganze ist eine Reihe und somit wird immer wieder das Selbe neu ermittelt. Je nach Zahl und Fall muss auch immer besser angenähert werden. Dadurch braucht das ganze erstens immer recht viel Zeit, und zweitens auch immer je nach Genauigkeit wieder länger, oder eben nich.

    Darum löst man das normalerweise eben über eine Lookup-Table: Hier habe ich schlichtweg eine Liste, die vom kleinstmöglichen Wert, bis zum größtmöglichen Wert in vielen Unterschritten die Wurzel bereits ausgerechnet. Wenn ich jetzt zum Beispiel die Wurzel von 1 wissen will, dann suche ich in der Liste das passende Ergebnis. Wenn ich jetzt aber die Wurzel aus 1.2 haben will, und dieser Wert ist nicht in der Liste, dann suche ich mir die beiden Werte heraus,z wischen denen diese Zahl steht. Sagen wir einmal, es sind 1 und 2.

    Laut unserer Liste wissen wir also, das unser Ergebnis zwischen 1 und 1.41421 liegen muss. Darum interpolieren wir zwischen den beiden Werten. Um an ein möglichst genaues Ergebnis finden zu können, überlegen wir uns einmal, wie eine Wurzel-Funktion aussieht:
    http://www.mathematik.net/wurzel-fkt/WF1S10P4.gif

    Jetzt suchen wir uns also eine Funktion, die dieser Kurve recht nahe kommt. Wir machen es uns einfach und interpolieren einfach linear: Wir rechnen uns also die Steigung aus, verlagern geistig die Axen und ermitteln den Punkt auf dem ca die gewollte Wurzel liegt. Und schon haben wir es geschafft.




    Da du programmieren lernen willst, gebe ich dir noch einen Tipp:
    #define BR cout<<'\n';

    Verwende so etwas niemals. Verwende den Praeprozessor nur dann, wenn es sein muss. Also, wenn du zum Beispiel zwischen Versionen unterscheiden willst, oder etwas dergleichen. Wenn deine Projekte einen gewissen Umfang übersteigen, dann wirst du bemerken, das ein großer Teil der Compile-Time vom Praeprozessor verbraucht wird.
    Außerdem macht das den ganzen Source unübersichtlich. Verwende lieber Konstante Werte, inline-Funktionen, etc.

  9. #9

    Users Awaiting Email Confirmation

    ok, dein Vortrag, klang ziemlich wissenschaftlich, x_{n+1} = (x_{n} + z/x_{n})/2, habe ich ehrlich gesagt nicht verstanden, weil x_{n+1} mir nicht sagt was das x ist und was das{}ist, aber ich denke ich habe verstanden was du mit der schnelleren Wurzelfunktion meinst, nämlich das die groben Werte schon vorgegeben sind.
    Auch das mit define habe ich eingesehen, aber jetzt noch zwei Fragen:
    1. Wie benutzt man dann diese schon vorgegebene Wurzelfunktion?
    2. Weshalb wird dann der Code von mir( auch wenn er nur bei kleineren Zahlen geeignet ist ) falsch gewertet, also dass bei Wurzel aus 4 2.001 rauskommt? Anscheinend scheint er ja b*b=4 und a=4 ja nicht als gleich anzusehen.

    @Mog:
    Sry, das ich deine x_{n+1} = (x_{n} + z/x_{n})/2
    Funktion nicht verstandfen habe, aber eigentlich habe ich ne 2+ in Matte

  10. #10
    Zitat Zitat von Tridestaros Beitrag anzeigen
    ok, dein Vortrag, klang ziemlich wissenschaftlich, x_{n+1} = (x_{n} + z/x_{n})/2, habe ich ehrlich gesagt nicht verstanden, weil x_{n+1} mir nicht sagt was das x ist und was das{}ist, aber ich denke ich habe verstanden was du mit der schnelleren Wurzelfunktion meinst, nämlich das die groben Werte schon vorgegeben sind.
    Auch das mit define habe ich eingesehen, aber jetzt noch zwei Fragen:
    1. Wie benutzt man dann diese schon vorgegebene Wurzelfunktion?
    2. Weshalb wird dann der Code von mir( auch wenn er nur bei kleineren Zahlen geeignet ist ) falsch gewertet, also dass bei Wurzel aus 4 2.001 rauskommt? Anscheinend scheint er ja b*b=4 und a=4 ja nicht als gleich anzusehen.

    @Mog:
    Sry, das ich deine x_{n+1} = (x_{n} + z/x_{n})/2
    Funktion nicht verstandfen habe, aber eigentlich habe ich ne 2+ in Matte

    1)
    C: #include <math.h>, bzw. cmath in Cpp.

    double sqrt(double x)


    2) && @:
    Siehe was ich geschrieben habe, das ist eine ganz einfache Formel.

    X_{b} bedeutet eigentlich nur, das ein b nach dem X tief gestellt steht. Schau dir mal den Anhang an, so angeschrieben verstehst du es sicher.
    Miniaturansichten angehängter Grafiken Miniaturansichten angehängter Grafiken Foo.png  

  11. #11

    Users Awaiting Email Confirmation

    ok, deine Funktion habe ich jetzt auch verstanden, aber immer noch mein Hauptproblem:
    Warum kommt eine höhere Zahl raus,(immer um 0.001)?
    Der code ist doch richtig, oder?
    Versucht doch sonstmal das Programm selbst zu compilieren.

Berechtigungen

  • Neue Themen erstellen: Nein
  • Themen beantworten: Nein
  • Anhänge hochladen: Nein
  • Beiträge bearbeiten: Nein
  •