// binomial_test.cpp : Definiert den Einstiegspunkt für die Konsolenanwendung.
//

#include "stdafx.h"
#include "mpir.h"

// maximum n
#define MAXN 99

// maximum k
#define MAXK 25

// this type should be able to contain binCoef[v][k] and binCoef[v][m]
typedef unsigned __int64 rankType;

// this type should be able to contain binomial coefficients needed
typedef unsigned __int64 binCoefType;

// Place where to save the coef
binCoefType binCoef[MAXN + 1][MAXN + 2] = {0};

//////////////////////////////////////////////////////////////////////////
// MPIR Binominal calc
//////////////////////////////////////////////////////////////////////////
rankType mpir_bincoef(unsigned long int n, unsigned long int k)
{
	rankType ret = 0;
	mpz_t result;
	mpz_init2(result,128);
	mpz_bin_uiui(result,n,k);
	ret = mpz_get_d(result);
	mpz_clear(result);
	return ret;
}

//////////////////////////////////////////////////////////////////////////
// Normal binominal calc
//////////////////////////////////////////////////////////////////////////
void calculateBinCoefs(void)
{
	int v,k;

	for(v = 0; v <= MAXN; v++) {
		binCoef[v][0] = binCoef[v][v] = 1;
		binCoef[v][v+1] = 0;
		for(k = 1; ((k <= v - 1) && (k<=MAXK)); k++) {
			binCoef[v][k] = binCoef[v - 1][k - 1] + binCoef[v - 1][k];
			if(binCoef[v][k] < binCoef[v - 1][k - 1] ||
				binCoef[v][k] < binCoef[v - 1][k] ||
				binCoef[v - 1][k - 1] == 0 ||
				(binCoef[v - 1][k] == 0 && k < v))
				binCoef[v][k] = 0; /* there was an overflow */
			if (binCoef[v][k] != mpir_bincoef(v,k))
			{
				printf("NN::%2d - %2d = %I64u\n",v,k, binCoef[v][k]);
				printf("MM::%2d - %2d = %I64u\n",v,k, mpir_bincoef(v,k));
			}
		}
	}
}

int _tmain(int argc, _TCHAR* argv[])
{
	calculateBinCoefs();
	return 0;
}

