C Programm springt mir nicht aus meiner for-Schleife raus

#6472597
Lesenswert?

Hallo zusammen,

ich bin gerade dabei nach einer Aufgabenstellung ein Programm zu 
schreiben, durch das ich raus bekomme wie viele Zahlenreihen ich 
benötige um auf 3.41 zu kommen.

π = 4/1 -  4/3 +  4/5 -  4/7 + ...

Das bekomme ich aktuell schon raus, allerdings mit einem manuellen 
rausspringen aus der Schleife mit dem Break und anschließenden 
durchschauen der Ausgabe.

--> mit 119 Zeichenketten komme ich auf 3.149996.

Ist es irgendwie möglich das ich beim Wert 3.41 aus der for-Schleife 
springe?
Meine Vermutung ist das es hier einfach nicht nur die 3.41 
berücksichtigt sondern auch die hinteren Stellen abgleicht. Hab auch 
schon von 3.139999 bis 3.410000 abgefragt, hier springt er mir aber auch 
nicht raus.

Kann mir jemand vielleicht einen Tipp geben wie das Programm nur die 
3.41 beachtet? Ich hätte eben gerne noch das es so lange durchläuft bis 
zur ersten 3.41 und dann eben stehen bleibt.
1
#include <stdio.h>
2

3
int main(void) {
4
  double pi = 0;  
5
  int count = 1;
6
  double n1 = 5.0; 
7
  double n2 = 7.0; 
8

9
  pi = (4 / 1.0) - (4 / 3.0);
10

11
  for (count = 3; pi >= 3.139 || pi <= 3.141; count++) {
12
    if (count % 2 == 1 ) {                
13
      pi = pi + (4.0 / n1);
14
      n1 = n1 + 4.0;
15
    }
16
    else {
17
      pi = pi - (4.0 / n2);
18
      n2 = n2 + 4.0;
19
    }
20
    printf("%f, %d\n", pi, count);
21
    if (count == 200) break; 
22
  }
23
}
Gast #6472617
Lesenswert?

Flo F. schrieb:

> schreiben, durch das ich raus bekomme wie viele Zahlenreihen ich
> benötige um auf 3.41 zu kommen.

3.14 meinst Du, aber Du solltest zunächst einmal verstehen, wie 
Fließkommazahlen überhaupt funktionieren. Das sind im Prinzip Brüche zur 
Basis zwei, und viele dezimal gesehen "glatte" Brüche haben keine exakte 
Repräsentation als binäre FLießkommazahlen. So wie z.B. 1/3 auch keine 
exakte dezimale Repräsentation mit endlich vielen Ziffern hat.

Davon ausgenommen sind nur Brüche, die sich als 1/(2^n) darstellen 
lassen, also etwa 0.5, 0.25, 0.125. Und damit auch deren Summen wie etwa 
0.75 oder 0.875.

Da 0.01 keine exakte Repräsentation als Fließkommazahl hat, hat 3.41 
auch keine.

Deswegen testest Du bei Fließkommazahlen niemals auf Gleichheit, sondern 
nur auf größer/größergleich und kleiner/kleinergleich, oder auf 
Intervalle.
Gast #6472623
Lesenswert?

Flo F. schrieb:
> Ich hätte eben gerne noch das es so lange durchläuft bis
> zur ersten 3.41 und dann eben stehen bleibt.

Dann veränderst du die Abbruchbedingung deiner Schleife:

Flo F. schrieb:
> for (count = 3; pi >= 3.139 || pi <= 3.141; count++)

Die Vergleiche müssen genau umgekehrt sein: Du willst die Iteration 
fortsetzen, bis zu im gewünschten Intervall angekommen bist. Die 
logische Verknüpfung ist dann auch anders ...


Außerdem willst du auch den Schleifenrumpf überdenken. Das geht ohne 
if/else erheblich kürzer, einfacher und logischer.
Gast #6472627
Lesenswert?

Mit allem Respekt: Das ist ja ein furchtbar unverständliches 
Geschreibsel.

Natürlich kann man erkennen, dass es um eine Variante der Leibnizschen 
Näherung von Pi geht.
Offenbar geht es auch darum, eine Abbruchbedingung für die Schleife 
festzulegen.

OK. Aber nun schreibe mal bitte die Aufgabenstellung hin. Dann wird 
vielleicht klar, wo es hingehen soll.
Vermutlich ist der Kern der Aufgabe die Abbruchbedingung festzulegen und 
zu begründen. Sagt Dir das Wort "Konvergenz" aus dem Matheunterricht 
noch was? Was ist das?
Gast #6472631
Lesenswert?

Die Aufgabe ist nur ein Programm zur Berechnung der Kreiszahl pi mit der 
Leibnizschen Nährung zu erstellen.
Die Frage lautet wie viele Reihenglieder werden benötigt, hier komme ich 
eben auf die 119.
Gast #6472660
Lesenswert?

Na schön, Flo. Die Aufgabe ist leider fehlerhaft beschrieben, Deine 
Annahme unbegründet, aber lassen wir das mal.


Ich rate Dir dazu, ganz genau zu überlegen, für welche Zahlenbereich die 
Bedingung in Deiner for-Schleife wahr oder falsch ist.

Weiter rate ich Dir noch einmal im C-Buch nachzuschauen, was diese 
Bedingung genau bewirkt.

Dann rate ich Dir, noch genau zu überlegen, welche zwei Zahlen, gemäß 
der Aufgabenstellung die Zahl Pi "umgeben". Welche Rolle genau spielt 
dabei die Anzahl der Stellen.

Abschliessend rate ich Dir, Dich mit der Darstellung von 
Fliesskommazahlen im Computer noch einmal gründlich zu befassen. Welche 
Zahlen kann man genau und welche nur mit einem gewissen Fehler 
darstellen?
Gast #6472669
Lesenswert?

ich habe im Netz einen Trick gesehen wie man Fließkommazahlen auf x 
Stellen rundet:
1
gerundete_zahl=(int)(fliesskommazahl*100+0.5)/100.0; //runden auf 2 Stellen
Mit diesem Ansatz komme ich auf 153 Durchläufe:
1
   double pi_double = 0.0;
2
   int pi_int = 0;
3

4
   double num = 4.0; // numerator
5
   int den; // denominator
6

7
   int i;
8
   for (i = 1, den = 1; pi_int != 314; i++, den += 2) {
9
      pi_double += num / den;
10
      pi_int = (int)(pi_double * 100 + 0.5);
11

12
      printf("round(%f)=%f\n", pi_double, pi_int / 100.0);
13

14
      num *= -1;
15
   }
16
   printf("\nIterationen: i=%d\n", i);
Gast #6472701
Lesenswert?

ganze ohne Tricks. Auch 152 Durchläufe.
1
   double my_pi = 0.0;
2
   double num = 4.0; // numerator
3

4
   // num= denominator
5
   for (int i = 1, den = 1; my_pi < 3.135 || my_pi > 3.144;
6
        i++, den += 2) {
7
      my_pi += num / den;
8
      printf("%d: %f\n", i, my_pi);
9
      num *= -1;
10
   }
#6473378
Lesenswert?

Flo F. schrieb:
>   for (count = 3; pi >= 3.139 || pi <= 3.141; count++)

Das ist eine Endlosschleife. Egal welchen Wert pi hat, die Bedingung "pi 
ist größer gleich 3.139 ODER pi ist kleiner gleich 3.141" ist immer 
erfüllt.

Natürlich kann man auch aus einer Endlosschleife herausspringen. Die 
elegantere Lösung wäre freilich, sich die Abbruchbedingung für die 
Schleife so zu überlegen, dass sie eben nicht endlos läuft.
Gast #6473389
Lesenswert?

Mark B. schrieb:
> pi ist kleiner gleich 3.141

Pi ist weder kleiner noch gleich 3.141, da Pi, wenn ich mich recht 
entsinne, 3.14159..... ist. Sollte man da nicht eher einen Wert nehmen, 
der tatsächlich größer als Pi ist, damit Pi dann auch ne Chance hat, 
überhaupt kleiner zu sein als der Vergleichswert?
Gast #6475662
Lesenswert?

Robert K. schrieb:
> und warum ist bei Dir:
> pi = (4 / 1.0) - (4 / 3.0);
>
> Ist bei Dir pi am Ende eine ganz andere Konstante als die Kreiszahl

na komm, dass er das als Startwert nutzt um sich hoffentlich immer 
weiter Pi anzunähern ist ja schon doch sehr offensichtlich, oder nicht?

'sid
Gast #6478229
Lesenswert?

Unabhängig von deiner Lösung frage ich mich warum man iteriert wenn man 
das Endergebnis schon kennt. Ich würde erwarten, dass man bei 
Unterschreiten eines Schwellwertes für die Änderung abbricht.
#6478560
Lesenswert?

Flo D. schrieb:
> Hallo zusammen,

Flo schrieb:
> Die Aufgabe ist nur ein Programm

1. 2 Namen schon mal ungünstig!

Theor schrieb:
> Na schön, Flo. Die Aufgabe ist leider fehlerhaft beschrieben, Deine
> Annahme unbegründet, aber lassen wir das mal.

warum lassen?

es muss doch mal deutlich gesagt werden das man normalerweise nicht aus 
Schleifen springt, die sollen beendet werden wenn die Bedingung erfüllt 
ist!

der Titel ist schon denkbar unglücklich!
C-Buch und lernen ist die erste Pflicht vor sinnlosem C&P

abgesehen davon sehe ich nur 2 Posting vom TO, der hat sich 
offensichtlich längst verabschiedet, manche wollen solche Antworten halt 
nicht hören oder lesen, sie wollen "nur" Lösungen.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren