78 static IntType apply(IntType x)
80 if(((unsigned_m() - 1) & unsigned_m()) == 0)
81 return (unsigned_type(x)) & (unsigned_m() - 1);
88 static IntType add(IntType x, IntType
c)
90 if(((unsigned_m() - 1) & unsigned_m()) == 0)
91 return (unsigned_type(x) + unsigned_type(
c)) & (unsigned_m() - 1);
100 static IntType mult(IntType a, IntType x)
102 if(((unsigned_m() - 1) & unsigned_m()) == 0)
103 return unsigned_type(a) * unsigned_type(x) & (unsigned_m() - 1);
108 else if(m <= traits::const_max/a)
109 return mult_small(a, x);
110 else if(traits::is_signed && (m%a < m/a))
111 return mult_schrage(a, x);
113 return mult_general(a, x);
116 static IntType mult_add(IntType a, IntType x, IntType
c)
118 if(((unsigned_m() - 1) & unsigned_m()) == 0)
119 return (unsigned_type(a) * unsigned_type(x) + unsigned_type(
c)) & (unsigned_m() - 1);
122 else if(m <= (traits::const_max-
c)/a) {
126 return add(mult(a, x),
c);
129 static IntType pow(IntType a, uintmax_t
exponent)
134 result = mult(result, a);
142 static IntType invert(IntType x)
143 {
return x == 0 ? 0 : (m == 0? invert_euclidian0(x) : invert_euclidian(x)); }
151 static IntType mult_small(IntType a, IntType x)
157 static IntType mult_schrage(IntType a, IntType value)
159 const IntType
q = m / a;
160 const IntType
r = m % a;
162 return sub(a*(value%
q),
r*(value/
q));
165 static IntType mult_general(IntType a, IntType
b)
169 if(uintmax_t(modulus) <=
170 (::std::numeric_limits< uintmax_t>::max)() / modulus)
172 return static_cast<IntType
>(uintmax_t(a) *
b % modulus);
178 static IntType sub(IntType a, IntType
b)
186 static unsigned_type unsigned_m()
189 return unsigned_type((std::numeric_limits<IntType>::max)()) + 1;
191 return unsigned_type(m);
196 static IntType invert_euclidian(IntType
c)
218 static IntType invert_euclidian0(IntType
c)
226 IntType max = (std::numeric_limits<IntType>::max)();