#include <iostream>
#include <iomanip>
using namespace std;

#include <math.h>
#include <stdlib.h>
#include "Rational.h"

Rational harmonic(int n) {
  Rational r = 1;
  for (int i=2; i<=n; ++i) r += Rational(1,i);
  return r;
}

Rational binomial(int n, int k) {
  if (n < 0) { cerr << "1st index out of range" << endl; exit(1); }
  if (k < 0 || k > n) { cerr << "2nd index out of range" << endl; exit(1); }
  if (k > n-k) k = n-k;
  if (k == 0) return 1;
  return Rational(n-k+1, k) * binomial(n, k-1);
}

Rational bernoulli(int n) {
  if (n < 0) { cerr << "index out of range" << endl; exit(1); }
  else if (n == 0) return 1;
  else if (n == 1) return Rational(-1,2);
  if (n % 2) return 0;
  Rational r = 0;
  for (int k=0; k<n; ++k) {
    r -= binomial(n+1, k) * bernoulli(k);
  }
  r /= n+1;
  return r;
}

int main() {
  int n;

  cout.precision(8);
  cout << "n\tEuler Approx.\tHarmonic(n)" << endl;
  cout << "========================================" << endl;
  for (n=1; n<25; ++n) {
    Rational r = harmonic(n);
    double g = toDouble(r) - log((double)n);
    g -= (1.0/(2*n)) * (1.0 - (1.0/(6*n)));
    cout << n << '\t' << g << '\t' << r << endl;
  }

  cout << endl << "n\tBernoulli(n)" << endl;
  cout << "========================================" << endl;
  Rational b;
  for (n=0; n<23; ++n) {
    if ((b=bernoulli(n)) != 0) cout << n << '\t' << b << endl;
  }
}