-
Notifications
You must be signed in to change notification settings - Fork 0
/
GF.cpp
86 lines (72 loc) · 1.87 KB
/
GF.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
#include <exception>
#include <numeric>
#include "GF.hpp"
template <uint8_t P>
void GF<P>::fix(void) {
v = val % P;
v = v >= 0 ? v : P - v;
}
template <uint8_t P>
GF<P>::GF(const int64_t val) noexcept : v(val) {
if (P == 0) { throw new std::runtime_error("field must have at list one element"); }
fix();
}
template <uint8_t P>
GF<P> &GF<P>::operator+=(const GF<P> &val) noexcept {
v += val.v;
fix();
return *this;
}
template <uint8_t P>
GF<P> GF<P>::operator+(const GF<P> &val) noexcept {
return GF<P>(v) += val;
}
template <uint8_t P>
GF<P> &GF<P>::operator-=(const GF<P> &val) noexcept {
v -= val.v;
fix();
return *this;
}
template <uint8_t P>
GF<P> GF<P>::operator-(const GF<P> &val) noexcept {
return GF<P>(v) -= val;
}
template <uint8_t P>
GF<P> &GF<P>::operator*=(const GF<P> &val) noexcept {
v *= val.v;
fix();
return *this;
}
template <uint8_t P>
GF<P> GF<P>::operator*(const GF<P> &val) noexcept {
return GF<P>(v) *= val;
}
template <uint8_t P>
GF<P> &GF<P>::MulInv(const GF<P> &val) {
int64_t a = val.v, b = P, x, y, q, r, x1 = 0, x2 = 1, y1 = 1, y2 = 0;
while (b > 0) {
q = a / b, r = a % b;
x = x2 - q * x1, y = y2 - q * y1;
a = b, b = r, x2 = x1, x1 = x, y2 = y1, y1 = y;
}
if (a != 1) { throw new std::runtime_error("multiplicative inverse not exists"); }
return new GC<p>(x2);
}
template <uint8_t P>
GF<P> &GF<P>::operator/=(const GF<P> &val) noexcept(false) {
if (val.v == 0) { throw new std::runtime_error("division by zero"); }
v *= MulInv(val.v);
return *this;
}
template <uint8_t P>
GF<P> GF<P>::operator/(const GF<P> &val) noexcept {
return GF<P>(v) /= val;
}
template <uint8_t P>
bool GF<P>::operator==(const GF<P> &val) const noexcept {
return v == val.v;
}
template <uint8_t P>
bool GF<P>::operator!=(const GF<P> &val) const noexcept {
return v != val.v;
}