5 class cl_heap_modint_ring_pow2 : public cl_heap_modint_ring {
6 SUBCLASS_cl_heap_modint_ring()
9 cl_heap_modint_ring_pow2 (const cl_I& m, uintC m1); // m = 2^m1
11 ~cl_heap_modint_ring_pow2 () {}
12 // Additional information.
16 static inline const cl_I pow2_reduce_modulo (cl_heap_modint_ring* _R, const cl_I& x)
18 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
19 return ldb(x,cl_byte(R->m1,0));
22 static const _cl_MI pow2_canonhom (cl_heap_modint_ring* R, const cl_I& x)
24 return _cl_MI(R, pow2_reduce_modulo(R,x));
27 static const _cl_MI pow2_plus (cl_heap_modint_ring* _R, const _cl_MI& x, const _cl_MI& y)
29 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
30 var cl_I zr = x.rep + y.rep;
31 return _cl_MI(R, ldb(zr,cl_byte(R->m1,0)));
34 static const _cl_MI pow2_minus (cl_heap_modint_ring* _R, const _cl_MI& x, const _cl_MI& y)
36 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
37 var cl_I zr = x.rep - y.rep;
38 return _cl_MI(R, ldb(zr,cl_byte(R->m1,0)));
41 static const _cl_MI pow2_uminus (cl_heap_modint_ring* _R, const _cl_MI& x)
43 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
44 var cl_I zr = - x.rep;
45 return _cl_MI(R, ldb(zr,cl_byte(R->m1,0)));
48 static const _cl_MI pow2_one (cl_heap_modint_ring* _R)
50 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
51 return _cl_MI(R, R->m1==0 ? 0 : 1);
54 static const _cl_MI pow2_mul (cl_heap_modint_ring* _R, const _cl_MI& x, const _cl_MI& y)
56 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
57 var cl_I zr = x.rep * y.rep;
58 return _cl_MI(R, ldb(zr,cl_byte(R->m1,0)));
61 static const _cl_MI pow2_square (cl_heap_modint_ring* _R, const _cl_MI& x)
63 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
64 var cl_I zr = square(x.rep);
65 return _cl_MI(R, ldb(zr,cl_byte(R->m1,0)));
68 // Timing comparison with std_recip, on a i486 33 MHz running Linux:
69 // timeMIpow2recip N inverts an (N*32)-bit number.
70 // N std_recip pow2_recip
80 static const cl_MI_x pow2_recip (cl_heap_modint_ring* _R, const _cl_MI& x)
82 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
83 var const cl_I& xr = x.rep;
88 throw division_by_0_exception();
90 return cl_notify_composite(R,xr);
92 return cl_MI(R, cl_recip2adic(R->m1,xr));
95 // Timing comparison with std_div, on a i486 33 MHz running Linux:
96 // timeMIpow2div N divides two (N*32)-bit numbers.
105 static const cl_MI_x pow2_div (cl_heap_modint_ring* _R, const _cl_MI& x, const _cl_MI& y)
107 var cl_heap_modint_ring_pow2* R = (cl_heap_modint_ring_pow2*)_R;
108 var const cl_I& yr = y.rep;
113 throw division_by_0_exception();
115 return cl_notify_composite(R,yr);
117 return cl_MI(R, cl_div2adic(R->m1,x.rep,yr));
120 static cl_modint_addops pow2_addops = {
127 static cl_modint_mulops pow2_mulops = {
140 static void cl_modint_ring_pow2_destructor (cl_heap* pointer)
142 (*(cl_heap_modint_ring_pow2*)pointer).~cl_heap_modint_ring_pow2();
145 cl_class cl_class_modint_ring_pow2 = {
146 cl_modint_ring_pow2_destructor,
147 cl_class_flags_modint_ring
151 inline cl_heap_modint_ring_pow2::cl_heap_modint_ring_pow2 (const cl_I& m, uintC _m1)
152 : cl_heap_modint_ring (m, &std_setops, &pow2_addops, &pow2_mulops), m1 (_m1)
154 type = &cl_class_modint_ring_pow2;