#include "num.h"

Num::Num(int value, int modulo) {
    this -> value = (modulo != 0) ? value % modulo : value;
    this -> modulo = modulo;
}

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

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

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

Num Num::operator * (const Num &other) {
    int64_t val = (static_cast<int64_t> (this->value) *
                   other.value) % this->modulo;
    return Num( static_cast<int>(val), this->modulo);
}

Num Num::operator + (int num) {
    num %= this->modulo;
    return Num(this->value + num, this->modulo);
}

Num Num::operator - (int num) {
    num %= this->modulo;
    return Num(this->value - num, this->modulo);
}

Num Num::operator * (int num) {
    num %= this->modulo;
    return Num(this->value * num, this->modulo);
}

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

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

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

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

Num &Num::operator -= (int num) {
    this->value -= num;
    while (this->value < 0) {
        this->value += this->modulo;
    }
    this->value %= this->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;
}