Laden...

Reihenberechnung ohne pow

Erstellt von Calanthe vor 5 Jahren Letzter Beitrag vor 5 Jahren 1.782 Views
C
Calanthe Themenstarter:in
4 Beiträge seit 2018
vor 5 Jahren
Reihenberechnung ohne pow

Hallo zusammen,

folgendes Problem ist mir über den Weg gelaufen:
Ich soll für den double x = 2.0 die Reihe 1.0/x - 2.0/x3 + 1.0/x5 - 2.0/x7 + ... berechnen und das Ergebnis ausgeben. Allerdings soll die Reihe dann abbrechen, wenn einer der beiden Terme, also entweder 1.0/xi oder 2.0/x^i den Wert 1.0E-9 unterschreitet. Wichtig ist, dass ich die pow-Funktion nicht benutzen darf.

Jetzt zermartere ich mir als Anfänger das Hirn schon seit ein paar Tagen mit dieser Problemstellung mit folgenden Ansätzen:

i ist ungerade.

i % 2 =1

Ich brauche eine for-Schleife, von der ich noch nicht ganz weiß, wie sie aussehen soll, bzw wie ich die Terme darin verbasteln soll. Und am meisten Kopfzerbrechen bereitet mir, wie dann i mitläuft..

Über Denkanstöße, die mich eigenständig zur Lösung führen, wäre ich absolut dankbar.

C
2.122 Beiträge seit 2010
vor 5 Jahren

Was bedeutet "wie i mitläuft"? Eine for Schleife ist doch genau dafür gedacht dass eine Variable von Durchlauf zu Durchlauf geändert wird. Irgendwie geändert wird.

Schau dir mal diese Rechnung an. Was lässt sich daraus wie in eine Schleife packen? Da bist du sicher schon auf einem richtigen Weg.

x^i mit ganzzahligem i kann man leicht ohne Pow berechnen.

4.942 Beiträge seit 2008
vor 5 Jahren

Du brauchst doch nur bei jedem Teilglied (innerhalb der Schleife) für den Nenner \*= x*x rechnen.

C
2.122 Beiträge seit 2010
vor 5 Jahren

Ich glaube so viel Hinweis wollte er (löblicherweise) gar nicht haben.

C
Calanthe Themenstarter:in
4 Beiträge seit 2018
vor 5 Jahren

Kann ich eine for-Schleife in eine for-Schleife basteln und in beiden dann Variablen benutzen, die ich vorher deklariere? 🤔

C
Calanthe Themenstarter:in
4 Beiträge seit 2018
vor 5 Jahren

So, nach langem Überlegen hab ich jetzt was gebastelt, was tut, was es soll. Leider sieht es, finde ich, etwas unübersichtlich aus.

double x = 2.0;
            int exponent = 1;
            double ergebnis = 0;
            bool plus = true;

            for(; ; )
            {
                double term = 0;
                double nenner = x;

                for (int i = 1; i < exponent; ++i)
                {
                    nenner *= x;
                }

                switch (plus)
                {
                    case true:
                        term = (1.0 / nenner);
                        break;
                    case false:
                        term = -(2.0 / nenner);
                        break;
                }

                if (Math.Abs(term) < 1.0E-9)
                {
                    break;
                }

                ergebnis += term;
                exponent += 2;

                plus = !plus;
            }

            Console.WriteLine(ergebnis);

Wenn jemand noch Vorschläge hat, wie man es einfacher machen kann, nehme ich sie dankbar an.

16.842 Beiträge seit 2008
vor 5 Jahren

Zur Übersichtlichkeit:

  • Statt for(;;) eben ne while(true)-Schleife.
  • Ein switch für ein Bool is deutlich am Ziel vorbei: dafür gibt es if.

Statt bool plus = true; eben sprechende Namen wie bool isPositive= true;
Einfache Änderungen mit ein paar Grundprinzipien macht das schnell übersichtlicher.
Dazu noch das ein oder andere Code-Kommentar, sodass nicht nur Mathe Genies den Code verstehen 😉
[Artikel] C#: Richtlinien für die Namensvergabe

C
Calanthe Themenstarter:in
4 Beiträge seit 2018
vor 5 Jahren
double x = 2.0;
            int exponent = 1;
            double ergebnis = 0;
            bool isPositive = true;

            for(; ; )
            {
                double term = 0;
                double nenner = x;

                for (int i = 1; i < exponent; ++i)
                    nenner *= x;


                if (isPositive == true)
                    term = (1.0 / nenner);
                else
                    term = -(2.0 / nenner);

                if (Math.Abs(term) < 1.0E-9)
                    break;

                ergebnis += term;
                exponent += 2;

                isPositive = !isPositive;
            }

            Console.WriteLine(ergebnis);

So sieht das jetzt aus. Was du mit der Umwandlung in eine while(true) Schleife meinst, ist mir aber noch nicht ganz klar. Grundsätzlich weiß ich, wie man eine Schleife in eine andere wandelt, aber wie das bei einem leeren Kopf funktioniert, weiß ich nicht.

/edit:
Kommentiert ist das nur noch nicht, weil ich das komplette Projekt noch "verschönere" 😉

4.942 Beiträge seit 2008
vor 5 Jahren

Noch als Hinweis: Ich hatte extra die Berechnung des Nenners oben erwähnt, damit du innerhalb der Schleife diesen nicht immer wieder neu berechnen lassen mußt (also keine innere Schleife benötigst), also


double nenner = x;

while (true)
{
   // ...

   nenner *= x*x;

   // ...
}

(so entfällt auch die Variable exponent)

T
2.224 Beiträge seit 2008
vor 5 Jahren

Abt hat doch geschrieben wie due die Schleife ändert.
Du musst nur for(;;) durch while(true) setzen.
while Schleifen sollen solange laufen, wie bestimmte Bedingungen erfüllt sind während eine for Schleife eben einen bestimmten Bereich durchlaufen sollen bzw. nur für eine bestimmte Menge an Durchäufen.
Zwar sind leere for und while(true) gleich bedeutend, aber while(true) sind für endlose Schleifen offensichtlicher da manche nicht wissen, dass man for Schleifen auch leer lassen kann um das gleiche Ergebnis zubekommen.

Deine if (isPositive == true) kannst du auch abkürzen mit if (isPositive) was auch verständlicher ist wenn man es liest.

T-Virus

Developer, Developer, Developer, Developer....

99 little bugs in the code, 99 little bugs. Take one down, patch it around, 117 little bugs in the code.