#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;
}