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

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

   Freiwillige Zusatzaufgabe 40) - ln_approx.cpp
   Approximation an den natuerlichen Logarithmus ln

   Leonhard Fellermayr, Mat. Nr. 22128130XXXX

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

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

#include <iostream>
using namespace std;

const long double EPSILON_IEEE_64BIT = 1e-17;

/* Fortgesetztes Quadratwurzelziehen mittels sqrt() in funktionalem Stil:
   Die Aufgabenstellung wurde so verstanden, dass ein Ziehen der 2^n-ten
   Wurzel mittels a^(1/(2^n)) = powl (a, 1 / powl (2, n)) nicht erlaubt
   ist.									 */

long double do_n_sqrts (long double a, int n) {
	if (n > 0)
		return sqrt (do_n_sqrts (a, n-1));
	else return a; /* else */
}

long double v1 (long double a, int n) {
	return ( powl (2, n) * (do_n_sqrts (a, n) - 1) );
}

long double v2 (long double a, int n) {
	long double nenner = 1;
	for (int k = 1; k <= n; k++)
		nenner *= 1 + do_n_sqrts (a, k);
	return ( powl (2, n) * ((a-1) / nenner) );
}

void do_calc (long double a) {
	int n = 0;
	printf ("==> APPROXIMATION FUER a = %Lg <==\n\n", a);
	printf ("|   n |         Verfahren 1 |         Verfahren 2 |       log() von C++ |\n");
	printf ("-------------------------------------------------------------------------\n");
	while (fabsl (do_n_sqrts (a, n) - do_n_sqrts (a, ++n)) >= EPSILON_IEEE_64BIT)
		printf ("| %3d | % .16Lf | % .16Lf | % .16Lf |\n",
			n, v1 (a, n), v2 (a, n), log (a));
	printf ("\n\n");
}

int main () {
	do_calc (2);
	do_calc (10);
	do_calc (0.36789);
	return 0;
}
