69 lines
1.4 KiB
C++
69 lines
1.4 KiB
C++
#ifndef ZMOD_HPP_
|
|
#define ZMOD_HPP_
|
|
|
|
#include <iostream>
|
|
#include <gmpxx.h>
|
|
|
|
namespace zmod {
|
|
|
|
template <unsigned long Mod>
|
|
class ZMod {
|
|
mpz_class value;
|
|
|
|
public:
|
|
ZMod() : value {} {}
|
|
ZMod(long value) : ZMod{mpz_class{value}} {}
|
|
ZMod(mpz_class value) {
|
|
mpz_mod_ui(this->value.get_mpz_t(), value.get_mpz_t(), Mod);
|
|
}
|
|
|
|
auto operator+(ZMod const& rhs) const -> ZMod {
|
|
return {value + rhs.value};
|
|
}
|
|
|
|
auto operator+=(ZMod const& rhs) -> ZMod & {
|
|
value += rhs.value;
|
|
mpz_mod_ui(this->value.get_mpz_t(), value.get_mpz_t(), Mod);
|
|
return *this;
|
|
}
|
|
|
|
auto operator-() const -> ZMod {
|
|
return {-value};
|
|
}
|
|
|
|
auto operator-(ZMod const& rhs) const -> ZMod {
|
|
return {value - rhs.value};
|
|
}
|
|
|
|
auto operator-=(ZMod const& rhs) -> ZMod & {
|
|
value -= rhs.value;
|
|
mpz_mod_ui(value.get_mpz_t(), value.get_mpz_t(), Mod);
|
|
return *this;
|
|
}
|
|
|
|
auto operator*(ZMod const& rhs) const -> ZMod {
|
|
return {value * rhs.value};
|
|
}
|
|
|
|
auto operator*=(ZMod const& rhs) -> ZMod & {
|
|
value -= rhs.value;
|
|
mpz_mod_ui(value.get_mpz_t(), value.get_mpz_t(), Mod);
|
|
return *this;
|
|
}
|
|
|
|
auto inverse() const -> ZMod {
|
|
mpz_class m{Mod};
|
|
ZMod result;
|
|
mpz_invert(result.value.get_mpz_t(), value.get_mpz_t(), m.get_mpz_t());
|
|
return result;
|
|
}
|
|
|
|
auto friend operator<<(std::ostream & out, ZMod<Mod> const& x) -> std::ostream & {
|
|
return out << x.value.get_ui();
|
|
}
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|