/* **************************************************************

   Uebungen zur Analysis I fuer Informatiker - WS 2003/04
   Blatt 5

   Freiwillige Zusatzaufgabe 25a)
   neck.cpp

   Berechnung der Flaechen des einbeschriebenen bzw. umbeschriebenen
   regulaeren 2^n-Ecks (n = 2,3,4,...) via zweier Formeln

   Leonhard Fellermayr, Mat. Nr. 22128130XXXX

   Auch im WWW: http://www.slacky.de/files/uni/analysis/neck.cpp

***************************************************************	*/

#include <iostream>

#define ARITHM_ERR -4711

using namespace std;

/* In der Funktion sn () wurde auf die Verwendung rekursiven
   Programmierstils verzichtet, da beim Verfahren 2 gleich
   zwei rekursive Aufrufe stattfaenden. Dadurch erhoeht sich
   die Rechenzeit ganz erheblich.				*/

long double sn (int n, int v)	/* v = Verfahren (1 oder 2)	*/
{
	long double vals[n+1];

	vals[2] = sqrt (2.0);			    /* per def. */

	for (int i = 3; i <= n; i++) {

		if (4 - pow (vals[i-1], 2) == 4)
		  return ARITHM_ERR;	  /* Arithm. zu ungenau */

		switch (v) {		 /* welches Verfahren ? */
		  case 1: vals[i] = sqrt (2 - sqrt (4 - pow (vals[i-1], 2))); break;
		  case 2: vals[i] = vals[i-1] / sqrt (2 + sqrt (4 - pow (vals[i-1], 2))); break;
		}

	}

	return vals[n];		/* letzter Wert = Ergebnis	*/

} // sn ()

long double calc_a (int n, long double sn_val) /* Berechne An	*/
{
	return (pow (2.0, n-1) * sn_val) *
		sqrt (1 - pow (sn_val, 2) / 4);
} // calc_a ()

long double calc_b (int n, long double sn_val) /* Berechne Bn   */
{
	return (pow (2.0, n-1) * sn_val) /
		sqrt (1 - pow (sn_val, 2) / 4);
} // calc_b ()

int main ()
{

  /* Senkung der Rechenzeit durch Zwischenspeicherung		*/
  /* von sn (n, 1) und sn (n, 2) in sn_tmp			*/

  long double   sn_tmp[2];
  int           i, n = 2;

  /* Definierten Startwert zuweisen				*/
  sn_tmp[1] = sn_tmp[2] = 1;

  printf ("|  n ||         A     (Rek. 1)      B         ||         A     (Rek. 2)      B         |\n");
  printf ("----------------------------------------------------------------------------------------\n");

  /* Abbruch while-Schleife erst, wenn beide Verfahren ungenau	*/
  while ((sn_tmp[1] != ARITHM_ERR) | (sn_tmp[2] != ARITHM_ERR))  {

        /* sn nach beiden Verfahren berechnen und speichern	*/
        for (i = 1; i <= 2; i++) sn_tmp[i] = sn (n, i);

        printf  ("| %02d |", n);
        for (i = 1; i <= 2; i++)
                if (sn_tmp[i] != ARITHM_ERR)
                        printf ("| %.15Lf | %.15Lf |", calc_a (n,sn_tmp[i]), calc_b (n,sn_tmp[i]));
                else
			printf ("| -------- ARITHMETIK UNGENAU! -------- |");
        printf ("\n");

        n++;

  } // endwhile

} // main ()
