# [C] Pi berechnen



## Azi (28. Januar 2006)

Nach langer Zeit programmiere ich wieder etwas in C. Aber iregdnwie scheint das nicht so ganz zu funktionieren... Naja, hier der total kommentierte Code:

```
/*
Nach der Formel:
 pi 01 01 01 01 01 01 01 01 01 01 
 __=__-__+__-__+__-__+__-__+__-__ 
 04 01 03 05 07 09 11 13 15 17 19 ...
 */
#include <stdio.h>
int main(int argc, char** argv)
{
/* Wenn ein Parameter angegeben */
if(argc == 2){
              /* I ist der angegebene Parameter */
              int i=atoi(argv[1]);
              /* Unser Zähler, der bei jedem Durchgang hochgezählt wird */
              int counter;
              /* Pi muss natürlich viele Nachkommastellen haben, deshalb long double */
              long double pi=0;
              /* J wird am Ende unser Pi werden, also auch ein long double */
              long double j=0;
              /* K ist bei jeder Berechnung der Nenner des Bruches */
              int k=1;
              /* L dient zum Wechsel von Addition und Subtraktion */
              int l=2;
              /* Noch eine Ausgabe, die zeigt, dass das Programm nicht abgestürzt ist */
              printf("\nEs wird gerechnet");
              /* Die Schleife wird so oft wiederholt, wie der angegebene Parameter sagt */
              for(counter=0;counter<i;counter++){
                                                 /* Nochmal eine Ich-bin-nicht-abgestürzt-Ausgabe */
                                                 printf(".");
                                                 /* dieses mal die Addition */
                                                 if(l==2){
                                                          j=j+1/k;
                                                          /* L verkleinern, damit beim nächsten Mal subtrahiert wird */
                                                          l--;
                                                          /* den Nenner um 2 vergrößern */
                                                          k=k+2;
                                                          }
                                                 /* Und hier die Subtraktion */
                                                 else if(l==1){
                                                               j=j-1/k;
                                                               /* L vergrößern, damit beim nächsten Mal addiert wird */
                                                               l++;
                                                               /* den Nenner um 2 vergrößern */
                                                               k=k+2;
                                                               }
                                                 }
              /* Pi ist das jetzige J mal 4 */
              pi=j*4;
              /* und die Ausgabe */
              printf("\n\n\n\tPi ist %Lf\n\n\n",pi);
              }
/* Wenn kein Parameter angegeben... */           
else{
     printf("pi [Genauigkeit]");
     }
return 0;
}
```

Die Ausgabe ist andauernd folgende:

```
>pi 5

Es wird gerechnet.....


        Pi ist 0.000000
```


----------



## sceada (28. Januar 2006)

Nach langem herumspielen mit printf`s um zu sehen wo was nicht stimmt hab ichs jetzt..war eigentlich relativ einfach 
Soweit ich das beurteilen kann (bin aber auch nocht soo gut im C Programmieren  ) waren 2 "Fehler" im Code:
1. "long double" bei j und pi, laut einem Pdf über C welches ich habe gibts "long double" nicht, nur double. (long nur bei "long int")
2. Anscheinend funktioniert das Rechnen mit Double`s und k, als Integer nicht.
Wenn k auch ein Double ist (oder Float, geht auch) dann funktioniert es.

Also hier mal der Code, mit dem funktioniert es bei mir:

```
#include <stdio.h>
int main(int argc, char** argv)
{
if(argc == 2){
              int i=atoi(argv[1]);
              int counter;
              double pi=0;
              double j=0;
              double k=1;
              int l=2;
              printf("\nEs wird gerechnet");
              for(counter=0;counter<i;counter++){
                                                 printf(".");
                                                 if(l==2){
                                                          j=j+1/k;
                                                          l--;
                                                          k=k+2;
                                                          }
                                                 else if(l==1){
                                                               j=j-1/k;
                                                               l++;
                                                               k=k+2;
                                                               }
                                                 }
              pi=j*4;
              printf("\n\n\n\tPi ist %Lf\n\n\n",pi);
              }          
else{
     printf("pi [Genauigkeit]");
     }
     }
```
(Kommentare gelöscht damits nocht so lang wird  )

mfg, sceada


----------



## Azi (28. Januar 2006)

Vielen Dank, es klappt jetzt wirklich! Jetzt gibt es nur ein Problem: Pi kann nur auf 6 Stellen genau ausgerechnet werden. Wie komme ich nun an mehr Stellen?


----------



## elmyth (28. Januar 2006)

Off Topic:


> <k2xl> in 1998, i made a C++ program to calculate pi to a billion digits.
> <k2xl> i coded it on my laptop (pentium 2 i think) and then ran the program.
> <k2xl> the next day i got a new laptop but decided to keep the program running.
> <k2xl> it's been over seven years now since i ran it. and this morning it finished calculating.
> ...


----------



## Azi (28. Januar 2006)

elmyth hat gesagt.:
			
		

> Off Topic:
> 
> 
> > <k2xl> in 1998, i made a C++ program to calculate pi to a billion digits.
> ...


[Auch Off Topic]
      ROFLMAO, das is ja echt witzig! Passt auch echt gut, ich glaub, das mach ich auch mal, bis auf den Teil mit der Ausgabe^^
[/Auch Off Topic]

Jetzt aber bitte nicht vergessen, dass ich nach einer Möglichkeit suche, mehr Stellen hinter dem Komma zu bekommen.


----------



## sceada (28. Januar 2006)

Die einzige Möglichkeit die ich dafür kenne ist, die Ausgabe am Ende zu ändern in das hier:

```
printf("\n\n\n\tPi ist %1.16f\n\n\n",pi);
```

Damit werden z.B. 16 Nachkommastellen erzwungen (%1.16 -> 16 Nachstellen, %1.5 -> 5 Nachstellen, etc...)
Das Problem dabei ist, mehr als 16 Nachtstellen haben keinen Sinn da dann nur noch Nuller dastehen (habs grade getestet), ich nehme an das Double nicht mehr aufnehmen kann.
(ich habs auch mit Float getestet, das gleiche...16 Stellen ist max.)

Also wenn du mehr als 16 Stellen willst, musst du warten bis sich hier ein Profi meldet :>

mfg, sceada


----------



## Azi (28. Januar 2006)

sceada hat gesagt.:
			
		

> Also wenn du mehr als 16 Stellen willst, musst du warten bis sich hier ein Profi meldet :>



Hmm, schade. Aber zum Glück weiß ich bescheid, wie man einen C-Profi hier im Forum findet (-->Signatur)

*Edit:* Ich habe mit "Pi 10000000" folgendes bekommen: Pi ist 3.1415925535898470.


----------



## Matthias Reitinger (28. Januar 2006)

Ich bin zwar kein C-Profi… aber hier würde es sich anbieten, eine Bibliothek zu verwenden, die es erlaubt, Fließkommazahlen mit beliebiger Genauigkeit zu verarbeiten. Falls es auch C++ sein darf, könnte man hierbei auf CLN (Class Library for Numbers) zurückgreifen.


----------



## Azi (28. Januar 2006)

Das Problem ist, dass das Ding zur Installation make braucht - unter Windows ein kleines Problem. Ich habe zwar auch Gentoo Linux auf dem Computer, allerdings muss die Datei eine Windows-Exe sein.


----------



## Matthias Reitinger (28. Januar 2006)

Azi hat gesagt.:
			
		

> Das Problem ist, dass das Ding zur Installation make braucht - unter Windows ein kleines Problem.


Das ist kein kleines Problem, das ist überhaupt kein Problem


----------



## Azi (28. Januar 2006)

Soweit ich weiß läuft Dev-C++ damit, welches ich benutze. Und wie kann ich jetzt CLN installieren?


----------



## Matthias Reitinger (28. Januar 2006)

Hast du ein MSYS am Laufen? Wenn ja, dann einfach ./configure, make, make install.

Zuvor solltest du allerdings folgenden Patch anwenden: http://www.ginac.de/pipermail/cln-list/2005-April/000116.html


----------



## Azi (28. Januar 2006)

Ich glaub, bei mir läuft nichts, Dev-C++ nutzt irgendeinen Teil vo MinGW. Gut, ich installier es mal. Muss ich denn jetzt alle Pakete herunterladen? Wäre recht aufwendig, es dürften 100 sein...


----------



## Matthias Reitinger (28. Januar 2006)

Steht doch alles auf der Download-Seite:



			
				http://www.mingw.org/download.shtml#hdr8 hat gesagt.:
			
		

> MSYS is a self contained, win32 style installation package. To install it, simply download the MSYS .exe file and then execute the file. Once you've executed the installation package accept the License, look at the changes, choose the install directory, select if you want icons, etc. and when you are done you should have a working MSYS environment to execute your configure scripts in. If you need autoconf, automake, libtool, cvs, etc. you will want to also install the msysDTK package. Similar to MSYS, the download is an installation binary. It will default the directory location to your MSYS installation assuming that you've installed MSYS which you need to do anyway as the package is dependent on it.


----------



## Azi (1. Februar 2006)

Nach 3,5 Stunden hab ich die Installation abgebrochen, das hat einfach zu lange gedauert. Ich hab schließlich noch andere Dinge zu tun.

Gibt es vielleicht noch eine andere Möglichkeit?

Ich hab mal gelesen, dass man auch Strings benutzen kann. Wie soll das gehen? Wenn das wirklich so ist, dann wäre es nett, wenn man mir es am Besipiel 10/3 zeigt.


----------



## deepthroat (1. Februar 2006)

Hi.





			
				Azi hat gesagt.:
			
		

> Nach 3,5 Stunden hab ich die Installation abgebrochen, das hat einfach zu lange gedauert. Ich hab schließlich noch andere Dinge zu tun.


Was hast du da gemacht? MSYS zu installieren dauert doch max. 'ne Minute?! 


			
				Azi hat gesagt.:
			
		

> Ich hab mal gelesen, dass man auch Strings benutzen kann. Wie soll das gehen? Wenn das wirklich so ist, dann wäre es nett, wenn man mir es am Besipiel 10/3 zeigt.


Das geht indem du Arithmetische Operationen auf für Strings implementierst. Z.B. eine Addition könntest du ja wie in der Schule durchführen (schriftliche Addition), die Multiplikation könntest du auf die Addition zurückführen (ist aber natürlich sehr langsam). Usw.

Gruß


----------



## Azi (1. Februar 2006)

deepthroat hat gesagt.:
			
		

> Hi.Was hast du da gemacht? MSYS zu installieren dauert doch max. 'ne Minute?!


Das kompilieren vom CLN hat solange gedauert...


			
				deepthroat hat gesagt.:
			
		

> Das geht indem du Arithmetische Operationen auf für Strings implementierst. Z.B. eine Addition könntest du ja wie in der Schule durchführen (schriftliche Addition), die Multiplikation könntest du auf die Addition zurückführen (ist aber natürlich sehr langsam).


Langsam ist nicht so gut, erst recht nicht, wenn man 1000000 Stellen von Pi ausrechnen möchte...

*Edit: *Bei der Suche nach Algorithmen zur Berechnung von Pi sah ich oft ein E, wie hier:
http://www.uni-leipzig.de/~sma/pi_einfuehrung/ausblickpics/gesch15sw.gif
kann mir das vielleicht mal jemand erklären? Unser Mathelehrer ist derzeit krank...


----------



## TimN (1. Februar 2006)

Zu dem "E" auf dem Bild:
wenn ich mich nicht täusche, ist das ein Summenzeichen (oder wie auch immer man das nennt)
Das "funktioniert" so:
Du rehnest den Term hinter dem E aus, wobei du n=0 setzt. Dann rechnest du das gleiche für n=1 aus. Jetzt die beiden Zahlen addieren. Dann für n=4, n=5, ..... (bis unendlich^^ das steht über dem Zeichen...)



PS: korrigiert mich, falls ich mich täusche...


----------



## deepthroat (1. Februar 2006)

Naja, das E ist aber natürlich kein E sondern ein großes, griechisches Sigma bzw. S.



			
				Azi hat gesagt.:
			
		

> Langsam ist nicht so gut, erst recht nicht, wenn man 1000000 Stellen von Pi ausrechnen möchte...


Kommt drauf an, wie oft du das machen möchtest - wenn es nur ein paar Mal gebraucht wird (oder sogar nur einmal) würde das immer noch ausreichen. 

Gruß


----------



## Azi (1. Februar 2006)

Ganz so selten wird es nicht gebraucht, bei meinem jetzigen Code mehrere Millionen male. Aber ich kann ja sowieso nicht alle Stellen ausrechnen, das Problem liegt ja an der mangelnden Anzahl der Stellen. Meine jetzige Methode ist übrigens etwa 50 mal schneller als die im ersten Thread, aber das nur mal so nebenbei. Das ist auch nichts besonderes, die oben war nur besonders langsam . Ich zeigs euch mal:

```
/*
  2
pi    1      1
__  = __  +  __
       2       2
6     1      2     ...

*/
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <math.h>
int main(int argc, char** argv)
{
if(argc == 2){
              int i=atoi(argv[1]);
              double counter;
              double Zeit1=clock();
              double pi=0;
              printf("\nEs wird gerechnet");
              for(counter=1;counter<=i;counter++)
              {
               pi=pi+1/pow(counter,2);
              }
              pi=pi*6;
              pi=sqrt(pi);
              double Zeit2=clock();
              double Zeit3=(Zeit2-Zeit1)/CLOCKS_PER_SEC;
              double BM=Zeit3*86400/i;
              printf("\n\n\n%1.3f Sekunden bei %d Rechenschritten",Zeit3,i);
              printf("\Faktor ist %1.16f",BM);
              printf("\n\n\n\tPi ist %1.16f\n\n\n",pi);
              }         
else{
     printf("pi [Genauigkeit]");
     }
return 0;
}
```
In Zeile 31 steht "\ n A z i F a k t o r", (ohne Leerzeichen) aber den Teil " n A z i" (ohne Leerzeichen) streicht der aus irgend einem Grunde...

Und mal der Geschwindigkeitsvergleich:

Version 1:

```
12247.343 Sekunden bei 1410065408 Rechenschritten
AziFaktor ist 0.7504406740258109


       Pi ist 3.1415926528785243
```

Version 2:

```
226.125 Sekunden bei 1410065408 Rechenschritten
AziFaktor ist 0.0138555274735170


        Pi ist 3.1415926449781995
```

Hoffentlich gibt es eine andere Methode als das CLN...


----------



## deepthroat (2. Februar 2006)

Ich hab mal ein bißchen gesucht, und da bin ich auf MAPM gestoßen. Kompilieren ist ganz einfach und dauert max. 2 Minuten. Am besten lädst du dir für MinGW die Unix Distribution herunter, auspacken, dann unter msys "make -f makefile.unx" eintippen und fertig.

Auf der Seite findest du übrigens auch Sourcecode zur Berechnung von Pi in C und C++.

Gruß


----------



## relig86 (4. Dezember 2007)

hallo leute 
wer kann mir helfen?
Wie kann ich pi berechnen mit Hilfe dieser Summe i/2 =Summe (n!)/(2n-i)!!= 1+ 1/3 + 1*2/3*5 + 1*2*3/3*5*7


----------



## deepthroat (4. Dezember 2007)

relig86 hat gesagt.:


> hallo leute
> wer kann mir helfen?
> Wie kann ich pi berechnen mit Hilfe dieser Summe :pi/2 =Summe (n!)/(2n-i)!!= 1+ 1/3 + 1*2/3*5 + 1*2*3/3*5*7


Du könntest einen Taschenrechner benutzen; oder ein Abakus, oder ein Blatt Papier. ;-)

Du könntest auch ein C++ Programm dafür schreiben... Im Grunde hast du doch hier von Azi bereits einen guten Anfang. Du müßtest dir nur eine rekursive Bildungsvorschrift überlegen.

Du könntest auch *suchen.*

Gruß


----------



## Philipp9494 (9. Dezember 2007)

Hi

hab etwas gefunden, weis aber nicht ob's funktioniert. Hier mal der Link http://lnc.sourceforge.net
oder http://cplus.kompf.de/artikel/gmp.html

mfg

Philipp9494


----------



## jasam (28. Mai 2022)

Hallo. 
Ich habe denn zweiten und letzten Code in eclips kopiert und festgestellt, dass ich da nichts sehe wo man den Parameter i eingeben kann. Oder übersehe ich da was?


----------



## ByeBye 284669 (28. Mai 2022)

Dieser Thread ist aus dem Jahre 2006! Den muss man nicht unbedingt wiederbeleben!


jasam hat gesagt.:


> Oder übersehe ich da was?


Scheinbar. Der Parameter wird per Programmaufruf übergeben, Posting #1



Azi hat gesagt.:


> >pi 5


----------



## jasam (29. Mai 2022)

m.scatello hat gesagt.:


> Dieser Thread ist aus dem Jahre 2006! Den muss man nicht unbedingt wiederbeleben!
> 
> Scheinbar. Der Parameter wird per Programmaufruf übergeben, Posting #1


wenn ich das so eingebe kommt dann nur "pi [Genauigkeit]" und es wird nicht nach einer Zahl zum eingeben gefragt.


----------



## zerix (29. Mai 2022)

Wo gibst du das denn ein?
Wenn du das Programm in eclipse startest, musst du den Paramter in der Startkonfiguration angeben.


----------



## jasam (29. Mai 2022)

zerix hat gesagt.:


> Wo gibst du das denn ein?
> Wenn du das Programm in eclipse startest, musst du den Paramter in der Startkonfiguration angeben.


Ich befürchte das mit Startkonfiguration habe ich mich noch nicht beschäftigt. Wo kann man die Anleitung dazu finden? Oder könnte man den Code so umschreiben, dass man mit scanf es eingeben kann?


----------



## ByeBye 284669 (29. Mai 2022)

jasam hat gesagt.:


> Oder könnte man den Code so umschreiben, dass man mit scanf es eingeben kann?


Klar kann man das, warum auch nicht?


----------

