
//
//   自分自身と計算するテスト
//   さらに，自分自身と計算して自分自身に格納するテスト
//

#include <iostream>
#include <string>

#include "mint.hpp"

using namespace std;

const char *title = "";

void comp (const MultiInteger<4>& a, const MultiInteger<4>& b) {
  cout << " " << title << (a==b ? " - passed." : " - failed.") << endl;
}

#define ToMint(n) (MultiInteger<n>)(unsigned int)

//=============================================================================
void test_add () {
  cout << "-- test operator + ()" << endl;
  MultiInteger<4> mint1, mint2, mint3;

 //--------------
 title = "test 1-1";
  mint1 = "55555555555555555555";
  mint2 = "55555555555555555555";
  mint3 = "55555555555555555555";
  mint1 += mint1;
  comp (mint1, mint2 + mint3);

 title = "test 1-2";
  mint1 = "55555555555555555555";
  mint2 = "55555555555555555555";
  mint3 = "55555555555555555555";
  mint1 = mint1 + mint1;
  comp (mint1, mint2 + mint3);
}


//=============================================================================
void test_sub () {
  cout << "-- test operator - ()" << endl;
  MultiInteger<4> mint1, mint2, mint3;

 //------------------
 title = "test 1-1";
  mint1 = "123456789901234567890";
  mint2 = "123456789901234567890";
  mint3 = "123456789901234567890";
  mint1 -= mint1;
  comp (mint1, mint2 - mint3);

 title = "test 1-2";
  mint1 = "123456789901234567890";
  mint2 = "123456789901234567890";
  mint3 = "123456789901234567890";
  mint1 = mint1 - mint1;
  comp (mint1, mint2 - mint3);

 //------------------
 title = "test 2-1";
  mint1 = "123456789901234567890";
  mint1 -= mint1;
  comp (mint1, ToMint(4) 0);

 title = "test 2-2";
  mint1 = "123456789901234567890";
  mint1 = mint1 - mint1;
  comp (mint1, ToMint(4) 0);
}


//=============================================================================
void test_mul () {
  cout << "-- test operator * ()" << endl;
  MultiInteger<4> mint1, mint2, mint3;

 //------------------
 title = "test 1-1";
  mint1 = "1234567890123";
  mint2 = "1234567890123";
  mint3 = "1234567890123";
  mint1 *= mint1;
  comp (mint1, mint2 * mint3);

 title = "test 1-2";
  mint1 = "1234567890123";
  mint2 = "1234567890123";
  mint3 = "1234567890123";
  mint1 = mint1 * mint1;
  comp (mint1, mint2 * mint3);
}


//=============================================================================
void test_div () {
  cout << "-- test operator / ()" << endl;
  MultiInteger<4> mint1, mint2, mint3;

 //------------------
 title = "test 1-1";
  mint1 = "1234567890123";
  mint2 = "1234567890123";
  mint3 = "1234567890123";
  mint1 /= mint1;
  comp (mint1, mint2 / mint3);

 title = "test 1-2";
  mint1 = "1234567890123";
  mint2 = "1234567890123";
  mint3 = "1234567890123";
  mint1 = mint1 / mint1;
  comp (mint1, mint2 / mint3);


 //------------------
 title = "test 2-1";
  mint1 = "1234567890123";
  mint1 /= mint1;
  comp (mint1, ToMint(4) 1);

 title = "test 2-2";
  mint1 = "1234567890123";
  mint1 = mint1 / mint1;
  comp (mint1, ToMint(4) 1);
}

//=============================================================================
void test_mod () {
  cout << "-- test operator % ()" << endl;
  MultiInteger<4> mint1, mint2, mint3;

 //------------------
 title = "test 1-1";
  mint1 = "1234567890123";
  mint2 = "1234567890123";
  mint3 = "1234567890123";
  mint1 %= mint1;
  comp (mint1, mint2 % mint3);

 title = "test 1-2";
  mint1 = "1234567890123";
  mint2 = "1234567890123";
  mint3 = "1234567890123";
  mint1 = mint1 % mint1;
  comp (mint1, mint2 % mint3);


 //------------------
 title = "test 2-1";
  mint1 = "1234567890123";
  mint1 %= mint1;
  comp (mint1, ToMint(4) 0);

 title = "test 2-2";
  mint1 = "1234567890123";
  mint1 = mint1 % mint1;
  comp (mint1, ToMint(4) 0);

}


int main (int argc, char *argv[]) {
  try {
    test_add();
    test_sub();
    test_mul();
    test_div();
    test_mod();

  } catch (const char *msg) {
    cout << "exception: " << msg << endl;

  } catch (...) {
    cout << "unknown exception." << endl;
  }

  return 0;
}

