#include <LEDA/integer.h>

#if defined(__GNUG__)
#include <Integer.h>
#endif


template <class integer_t> 
void integer_test(integer_t, char* tname, int N, int* a, int la, int* b, int lb)
{
   int i;
   integer_t A  = 0;
   integer_t B  = 0;

   integer_t D,P,Q,R,S;

   newline;

   float T = used_time();

   cout << tname << endl;
   cout << "construction:   " << flush;
   for(i=0; i<la;    i++) { A <<= 32; A += a[i]; }
   for(i=0; i<lb;    i++) { B <<= 32; B += b[i]; }
   cout << string(" %4.2f",used_time(T)) << endl;

   cout << "addition:       " << flush;
   T = used_time();
   for(i=0; i < 100*N; i++) { S = A+B; }
   cout << string(" %4.2f",used_time(T)) << endl;

   cout << "subtraction:    " << flush;
   T = used_time();
   for(i=0; i < 100*N; i++) { D = A-B; }
   cout << string(" %4.2f",used_time(T)) << endl;

   if (S+D-A != A) cout << "error in addition/subtraction" << endl;


   cout << "multiplication: " << flush;
   T = used_time();
   for(i=0; i<N; i++) { P = A*B; }
   cout << string(" %4.2f",used_time(T)) << endl;

   cout << "division:       " << flush;
   for(i=0; i < N; i++) { Q = A/B; }
   cout << string(" %4.2f",used_time(T)) << endl;


   cout << "modulo:         " << flush;
   for(i=0; i < N; i++) { R = A%B; }
   cout << string(" %4.2f",used_time(T)) << endl;

   if (Q*B + R != A) 
     cout << "error in division/multiplication" << endl;
}


main()
{

  int N  = read_int("iterations = ");
  int la = read_int("size of A  = ");
  int lb = read_int("size of B  = ");

  int* a = new int[la];
  int* b = new int[lb];

  random_source ran;

  int i;
  for(i=0; i<la; i++) a[i] = ran();
  for(i=0; i<lb; i++) b[i] = ran();

  integer_test(integer(0),"LEDA integer",N,a,la,b,lb);

#if defined(__GNUG__)
  integer_test(Integer(0),"GNU Integer",N,a,la,b,lb);
#endif

  return 0;

 }
