#include <stdio.h>
#include <time.h>
#include <sys/time.h>
#ifdef _OPENMP
// wird nur dann vom Compiler beruecksichtigt, wenn _OPENMP definiert ist.
// Dies ist der Fall, wenn mit openMP Unterstuetzung kompiliert wird
  #include <omp.h>
#endif

#define f(A) (4.0/(1.0+A*A))
  //Anzahl der Iterationsschritte
const int n = 10000000;

int main (int argc, char** argv)
{
  /* Laufvariable fuer for-Schleife */
  int i;
  /** step: Schrittgroesse im Iterationsverfahren (= 1/n)
   *  actX: aktueller x Wert bei der Iteration
   * sum: Zwischensumme in der Iteration
   * pi: Endergebnis der Iteration
   */
  double step, actX, sum, pi;

  /*---- Zeitmessung mit gettimeofday() und omp_get_wtime() starten */
  clock_t t1,t2;
  struct timeval tv1, tv2;
  struct timezone tz;

#ifdef _OPENMP
  double wt1,wt2;
#endif

  gettimeofday (&tv1, &tz);
#ifdef _OPENMP
  wt1 = omp_get_wtime ();
#endif
  t1 = clock();
  
  /*---- Berechnung von pi, nutzt die Tatsache, dass
   *     pi = integral[0..1] (4/1+x^2) dx 
   */
  
  step = 1.0 / n;
  sum = 0.0;
  
  for (i = 1; i <= n; i++) {
    actX = step * ((double) i - 0.5);
    sum = sum +  f(actX);
  }
  pi = step * sum;
  
  /*---- Zeitmessung beenden */

  t2 = clock ();
#ifdef _OPENMP
  wt2 = omp_get_wtime();
#endif
  gettimeofday(&tv2, &tz);
  printf ("computed pi = %24.16g\n", pi);
  printf ("CPU time (clock) = %12.4g sec\n", (double)(t2-t1)/CLOCKS_PER_SEC);
#ifdef _OPENMP
  printf ("wall clock time (omp_get_wtime) = %12.4g sec \n", wt2-wt1);
#endif
  printf ("wall clock time (gettimeofday) = %12.4g sec \n", 
	  (tv2.tv_sec - tv1.tv_sec) + 
	  (tv2.tv_usec - tv1.tv_usec) * 1e-6);
  return 0;
}

