#include "num.h"
#include <cstdint>
Num::Num(int value, int modulo) {
  if ( modulo != 0 ) {
    this->value = value % modulo;
  }
  this->modulo = modulo;
}

Num & Num::operator=(const Num &other) {
  value = other.value;
  if ( modulo < other.modulo ) {
    modulo = other.modulo;
  }
  return *this;
}

Num Num ::operator+(const Num &other) {
  return Num(value + other.value, modulo);
}

Num Num::operator-(const Num &other) {
  return Num(value - other.value, modulo);
}

Num Num::operator*(const Num &other) {
  return Num(value*other.value, modulo);
}

Num Num::operator+(int num) {
  return Num(value+num, modulo);
}

Num Num:: operator-(int num) {
  return Num(value-num, modulo);
}

Num Num::operator*(int num) {
  return Num(value*num, modulo);
}

Num & Num::operator+=(const Num &other) {
  if ( other.modulo > modulo ) {
    modulo = other.modulo;
  }
  value+= other.value;
  this->value = this->value % modulo;
  return *this;
}

Num & Num::operator-=(const Num &other) {
  if ( other.modulo > modulo ) {
    modulo = other.modulo;
  }
  if ( value - other.value < 0 ) {
    value += modulo;
  }
  value -= other.value;
  return *this;
}

Num & Num::operator*=(const Num &other) {
  if ( other.modulo > modulo ) {
    modulo = other.modulo;
  }
  this->value *= other.value;
  this->value = this->value % modulo;
  return *this;
}

Num & Num::operator+=(int num) {
  value = static_cast<int>(((static_cast<int64_t>(value) +
    static_cast<int64_t>(num)) % static_cast<int64_t>(modulo)));
  return *this;
}

Num & Num::operator-=(int num) {
  if ( value - num < 0 ) {
    value += modulo;
  }
  value -= num;
  return *this;
}

Num & Num::operator*=(int num) {
  value = static_cast<int>(((static_cast<int64_t>(value) *
    static_cast<int64_t>(num)) % static_cast<int64_t>(modulo)));
  return *this;
}