3 class cl_heap_modint_ring_pow2 : public cl_heap_modint_ring {
4 SUBCLASS_cl_heap_modint_ring()
7 cl_heap_modint_ring_pow2 (const cl_I& m, uintL m1); // m = 2^m1
9 ~cl_heap_modint_ring_pow2 () {}
10 // Additional information.
15 #if !(defined(__GNUC__) && (__GNUC__ == 2) && (__GNUC_MINOR__ <= 90)) // workaround g++-2.7.2 and egcs-1.0.2-prerelease bug
18 const cl_I pow2_reduce_modulo (cl_heap_modint_ring* _R, const cl_I& x)
20 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
21 return ldb(x,cl_byte(R->m1,0));
24 static const _cl_MI pow2_canonhom (cl_heap_modint_ring* R, const cl_I& x)
26 return _cl_MI(R, pow2_reduce_modulo(R,x));
29 static const _cl_MI pow2_plus (cl_heap_modint_ring* _R, const _cl_MI& x, const _cl_MI& y)
31 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
32 var cl_I zr = x.rep + y.rep;
33 return _cl_MI(R, ldb(zr,cl_byte(R->m1,0)));
36 static const _cl_MI pow2_minus (cl_heap_modint_ring* _R, const _cl_MI& x, const _cl_MI& y)
38 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
39 var cl_I zr = x.rep - y.rep;
40 return _cl_MI(R, ldb(zr,cl_byte(R->m1,0)));
43 static const _cl_MI pow2_uminus (cl_heap_modint_ring* _R, const _cl_MI& x)
45 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
46 var cl_I zr = - x.rep;
47 return _cl_MI(R, ldb(zr,cl_byte(R->m1,0)));
50 static const _cl_MI pow2_one (cl_heap_modint_ring* _R)
52 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
53 return _cl_MI(R, R->m1==0 ? 0 : 1);
56 static const _cl_MI pow2_mul (cl_heap_modint_ring* _R, const _cl_MI& x, const _cl_MI& y)
58 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
59 var cl_I zr = x.rep * y.rep;
60 return _cl_MI(R, ldb(zr,cl_byte(R->m1,0)));
63 static const _cl_MI pow2_square (cl_heap_modint_ring* _R, const _cl_MI& x)
65 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
66 var cl_I zr = square(x.rep);
67 return _cl_MI(R, ldb(zr,cl_byte(R->m1,0)));
70 // Timing comparison with std_recip, on a i486 33 MHz running Linux:
71 // timeMIpow2recip N inverts an (N*32)-bit number.
72 // N std_recip pow2_recip
82 static const cl_MI_x pow2_recip (cl_heap_modint_ring* _R, const _cl_MI& x)
84 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
85 var const cl_I& xr = x.rep;
90 cl_error_division_by_0();
92 return cl_notify_composite(R,xr);
94 return cl_MI(R, cl_recip2adic(R->m1,xr));
97 // Timing comparison with std_div, on a i486 33 MHz running Linux:
98 // timeMIpow2div N divides two (N*32)-bit numbers.
107 static const cl_MI_x pow2_div (cl_heap_modint_ring* _R, const _cl_MI& x, const _cl_MI& y)
109 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
110 var const cl_I& yr = y.rep;
115 cl_error_division_by_0();
117 return cl_notify_composite(R,yr);
119 return cl_MI(R, cl_div2adic(R->m1,x.rep,yr));
122 static cl_modint_addops pow2_addops = {
129 static cl_modint_mulops pow2_mulops = {
143 inline cl_heap_modint_ring_pow2::cl_heap_modint_ring_pow2 (const cl_I& m, uintL _m1)
144 : cl_heap_modint_ring (m, &std_setops, &pow2_addops, &pow2_mulops), m1 (_m1) {}