C :: Aufgabe #165

3 Lösungen Lösungen öffentlich

Funktion um Pi zu berechnen.

Anfänger - C von Felix - 09.07.2017 um 21:59 Uhr
Schreibe eine Methode um Pi zu berechnen. Versuche Pi auf so viele Stellen wie möglich zu berechnen.

Lösungen:

vote_ok
von devnull (8860 Punkte) - 27.08.2017 um 22:37 Uhr
Quellcode ausblenden C-Code
/* Pi ueber Teilerfremdheit / Monte-Carlo */
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <math.h>

int ggT(int p, int q) {
  int r;
  
  while ((r=p%q) != 0) {
    p=q;
    q=r;
  }
  return q;
}

int main(void) {
  int n, nt, nh;
  int a, b;
  double rt, pi;
  
  for (;;) {
    printf("Anzahl Versuche (0=Ende): ");
    scanf("%d", &n);
    if (n==0) 
		break;
    srand(time(NULL));
    
    for (nt=nh=0; nt<n; nt++) {
      a = rand() + 1;
      b = rand() + 1;
      if (ggT(a,b)==1)    /* a,b teilerfremd */
        ++nh;
    }
    rt = 1.0*nh/nt;
    pi = sqrt(6.0/rt);
    printf("Versuche: %d, Pi-Approximation: %.6f\n", nt, pi);
  }
  return 0;
}
vote_ok
von devnull (8860 Punkte) - 28.08.2017 um 19:01 Uhr
Quellcode ausblenden C-Code
/* Kettenbruch rekursiv */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>

double qn(int n, int max) {
	if (n==0)
	  return 1.+1./qn(1,max);
	else if (n < max)
	  return 2.+(2.*n+1.)*(2.*n+1.)/qn(n+1,max);
	else
	  return 2.+2.*sqrt(n*n+n+1);
}
	
int main(void) {
  double pi;
  int n;
  
  while (1){
    printf("Anzahl Kettenbruchglieder (0=Ende): ");
    scanf("%d", &n);
    if (n==0) break;

    pi = 4.0/qn(0,n);
    printf("Kettenbruch Länge %d, Pi-Approximation: %.8f\n", n, pi);
  }
  return 0;
}
vote_ok
von devnull (8860 Punkte) - 21.10.2017 um 21:43 Uhr

Konsolenausgabe:

Anzahl Schritte: 5
0: 3.141592
1: 3.141592653589793
2: 3.14159265358979323846264
3: 3.1415926535897932384626433832795
4: 3.141592653589793238462643383279502884197

Quellcode ausblenden C-Code
/********************************************
 * pi_3.c   Pi mit Ramanujan-Formel
 ********************************************/
#include <stdlib.h>
#include <stdio.h>
#include <gmp.h>

/***********************************************
 *                oo                           *
 *           _    __                           *  
 *  1      \/8   \    (4n)!   (1103 + 26390n)  *
 * ---- = ------ /__ -------- ---------------  *
 *  pi     9801  n=0  (n!)^4      396^(4n)     *
 *                                             *
 **********************************************/
 
#define PI_1000 " 3.\
14159265358979323846264338327950288419716939937510\
58209749445923078164062862089986280348253421170679\
82148086513282306647093844609550582231725359408128\
48111745028410270193852110555964462294895493038196\
44288109756659334461284756482337867831652712019091\
45648566923460348610454326648213393607260249141273\
72458700660631558817488152092096282925409171536436\
78925903600113305305488204665213841469519415116094\
33057270365759591953092186117381932611793105118548\
07446237996274956735188575272489122793818301194912\
98336733624406566430860213949463952247371907021798\
60943702770539217176293176752384674818467669405132\
00056812714526356082778577134275778960917363717872\
14684409012249534301465495853710507922796892589235\
42019956112129021960864034418159813629774771309960\
51870721134999999837297804995105973173281609631859\
50244594553469083026425223082533446850352619311881\
71010003137838752886587533208381420617177669147303\
59825349042875546873115956286388235378759375195778\
18577805321712268066130019278766111959092164201989"
/* www-groups.dcs.st-and.ac.uk/history/HistTopics/1000_places.html */


/* find 1st different character in 2 strings */
char *strdiff(char *s1, char *s2) {
  char *p1, *p2;

  for (p1=s1,p2=s2; *p1 && *p1==*p2; p1++,p2++)
      ;
  return (*p1 || *p2) ? p1 : NULL;
}

int main() {
    mpz_t A0, B0, C0, D0;
    mpz_t A1, B1, C1, D1;
    mpz_t AC, BD;
    mpf_t fAC, fBD, fQn, fSq;
    mpf_t fpifac, fpisum, fpi;
    
    unsigned steps;
    unsigned n, n1, n4;
    unsigned long facl, c4;
    char pibuf[1024];
    char *p;
    
    /* Eingabe */
    printf("Anzahl Schritte: ");
    scanf("%u", &steps);

    /* GMP - Init */
	mpf_set_default_prec(4096);
    
    mpz_init_set_ui(A0, 1L);
    mpz_init_set_ui(B0, 1L);
    mpz_init_set_ui(C0, 1103L);
    mpz_init_set_ui(D0, 1L);
    
    mpz_init(A1); mpz_init(B1);
    mpz_init(C1); mpz_init(D1);
    mpz_init(AC); mpz_init(BD);
    
	mpf_init(fAC);    mpf_init(fBD);
	mpf_init(fQn);    mpf_init(fSq);
	mpf_init(fpifac); mpf_init(fpisum);
	mpf_init(fpi);

    /* constant factors */
	mpf_sqrt_ui(fSq, 8L);
	mpf_set_ui(fpifac, 9801L);
	mpf_div(fpifac, fpifac, fSq);
    c4 = 396L * 396L * 396L * 396L;

	mpf_set_z(fpisum, C0);

    for (n=0; n<steps; n++) {
		mpf_div(fpi, fpifac, fpisum);
		gmp_sprintf(pibuf, "%1003.1000Ff\n", fpi);
		
		/* print all matching pi digits */
		if ((p = strdiff(pibuf, PI_1000)) != NULL)
		  *p = 0;
		printf("%3d: %s\n", n, pibuf);
		
		/* calc next series element */
		n1=n+1;
		n4=4*n;
		facl = (n4+1)*(n4+2)*(n4+3)*(n4+4);
		mpz_mul_ui(A1, A0, facl);
		facl = n1*n1*n1*n1;
		mpz_mul_ui(B1, B0, facl);
		mpz_add_ui(C1, C0, 26390L);
		mpz_mul_ui(D1, D0, c4);
		mpz_mul(AC, A1, C1);
		mpz_mul(BD, B1, D1);
		mpf_set_z(fAC, AC);
		mpf_set_z(fBD, BD);
		mpf_div(fQn, fAC, fBD);
		
		/* add sum */
		mpf_add(fpisum, fpisum, fQn);
		
        /* init new loop */		
		mpz_set(A0, A1);
		mpz_set(B0, B1);
		mpz_set(C0, C1);
		mpz_set(D0, D1);
	}
    return 0;
}