forked from Whirligig231/number-field-factorization
-
Notifications
You must be signed in to change notification settings - Fork 0
/
modring.cpp
executable file
·138 lines (110 loc) · 3.21 KB
/
modring.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#include "modring.h"
mod::mod() {
this->base = 0;
this->value = 0;
}
mod::mod(mpz_class value) {
this->base = 0;
this->value = value;
}
mod::mod(mpz_class base, mpz_class value) {
this->base = base;
mpz_mod(this->value.get_mpz_t(), value.get_mpz_t(), base.get_mpz_t());
}
mod::mod(const mod &other) {
this->base = other.base;
this->value = other.value;
}
mod::mod(const mod &other, mpz_class value) {
this->base = other.base;
mpz_mod(this->value.get_mpz_t(), value.get_mpz_t(), other.base.get_mpz_t());
}
mpz_class mod::get_base() const {
return this->base;
}
mod &mod::operator=(mpz_class value) {
mpz_mod(this->value.get_mpz_t(), value.get_mpz_t(), this->base.get_mpz_t());
return *this;
}
mod &mod::operator=(const mod &other) {
this->base = other.base;
this->value = other.value;
return *this;
}
bool mod::operator==(const mod &other) const {
return (this->value == other.value);
}
bool mod::operator!=(const mod &other) const {
return (this->value != other.value);
}
mod &mod::operator+=(const mod &other) {
this->value += other.value;
this->base = (this->base == 0) ? other.base : this->base;
mpz_mod(this->value.get_mpz_t(), this->value.get_mpz_t(), this->base.get_mpz_t());
return *this;
}
mod &mod::operator-=(const mod &other) {
this->value -= other.value;
this->base = (this->base == 0) ? other.base : this->base;
mpz_mod(this->value.get_mpz_t(), this->value.get_mpz_t(), this->base.get_mpz_t());
return *this;
}
mod &mod::operator*=(const mod &other) {
this->value *= other.value;
this->base = (this->base == 0) ? other.base : this->base;
mpz_mod(this->value.get_mpz_t(), this->value.get_mpz_t(), this->base.get_mpz_t());
return *this;
}
mod &mod::operator/=(const mod &other) {
return (*this) *= other.inv();
}
mod mod::operator+(const mod &other) const {
return mod(*this) += other;
}
mod mod::operator-(const mod &other) const {
return mod(*this) -= other;
}
mod mod::operator*(const mod &other) const {
return mod(*this) *= other;
}
mod mod::operator/(const mod &other) const {
return mod(*this) /= other;
}
mod mod::operator-() const {
return mod(this->base, this->base - this->value);
}
mod mod::inv() const {
mpz_class g, s;
mpz_gcdext(g.get_mpz_t(), s.get_mpz_t(), NULL, this->value.get_mpz_t(), this->base.get_mpz_t());
if (g != 1) {
std::cout << "ERROR: attempt to invert non-invertible element" << std::endl;
int x = 0;
x = 1/x;
}
mpz_mod(s.get_mpz_t(), s.get_mpz_t(), this->base.get_mpz_t());
return mod(this->base, s);
}
std::ostream &operator<<(std::ostream &os, const mod &m) {
return os << m.value;
}
mod::operator mpz_class() {
return this->value;
}
mod make_mod(mpz_class base, mpz_class value) {
return mod(base, value);
}
std::function<mod(mpz_class)> to_mod(mpz_class base) {
return std::bind(make_mod, base, std::placeholders::_1);
}
mod util<mod>::zero() {
return mod(0, 0);
}
mod util<mod>::zero(const mod &reference) {
return mod(reference.get_base(), 0);
}
mod util<mod>::one(const mod &reference) {
return mod(reference.get_base(), 1);
}
mod util<mod>::from_int(int n, const mod &reference) {
return mod(reference.get_base(), n);
}