14 #ifndef __INCLUDED_SCOPIRA_TOOL_CONSTMOD_H__ 15 #define __INCLUDED_SCOPIRA_TOOL_CONSTMOD_H__ 21 #include <scopira/tool/limits.h> 22 #include <scopira/tool/platform.h> 33 template<
class IntType, IntType m>
37 static IntType add(IntType x, IntType c)
41 else if(c <= traits::max() - m)
42 return add_small(x, c);
43 else if(traits::is_signed)
44 return add_signed(x, c);
47 assert(!
"const_mod::add with c too large");
52 static IntType mult(IntType a, IntType x)
56 else if(m <= traits::max()/a)
57 return mult_small(a, x);
58 else if(traits::is_signed && (m%a < m/a))
59 return mult_schrage(a, x);
62 assert(!
"const_mod::mult with a too large");
67 static IntType mult_add(IntType a, IntType x, IntType c)
69 if(m <= (traits::max()-c)/a)
72 return add(mult(a, x), c);
75 static IntType invert(IntType x)
76 {
return x == 0 ? 0 : invert_euclidian(x); }
79 typedef std::numeric_limits<IntType> traits;
83 static IntType add_small(IntType x, IntType c)
91 static IntType add_signed(IntType x, IntType c)
99 static IntType mult_small(IntType a, IntType x)
104 static IntType mult_schrage(IntType a, IntType value)
106 const IntType q = m / a;
107 const IntType r = m % a;
111 value = a*(value%q) - r*(value/q);
118 static IntType invert_euclidian(IntType c)
121 BOOST_STATIC_ASSERT(m > 0);
122 #ifndef BOOST_NO_LIMITS_COMPILE_TIME_CONSTANTS 123 BOOST_STATIC_ASSERT(std::numeric_limits<IntType>::is_signed);
135 return (l2 < 1 ? l2 + m : l2);
140 return (l1 < 1 ? l1 + m : l1);
151 typedef unsigned int IntType;
153 static IntType add(IntType x, IntType c) {
return x+c; }
154 static IntType mult(IntType a, IntType x) {
return a*x; }
155 static IntType mult_add(IntType a, IntType x, IntType c) {
return a*x+c; }
165 typedef unsigned long IntType;
167 static IntType add(IntType x, IntType c) {
return x+c; }
168 static IntType mult(IntType a, IntType x) {
return a*x; }
169 static IntType mult_add(IntType a, IntType x, IntType c) {
return a*x+c; }
179 typedef uint64_t IntType;
181 static IntType add(IntType x, IntType c) {
return c == 0 ? x : mod(x+c); }
182 static IntType mult(IntType a, IntType x) {
return mod(a*x); }
183 static IntType mult_add(IntType a, IntType x, IntType c)
184 {
return mod(a*x+c); }
185 static IntType mod(IntType x) {
return x &= ((uint64_t(1) << 48)-1); }
Definition: archiveflow.h:20