include/symbolism/N.Binary.h

00001 
00004 inline size_t N::two_multiplicity() const
00005 {
00006     if(this_small)
00007     {
00008         return two_multiplicity_small();
00009     }
00010     else
00011     {
00012         return two_multiplicity_large();
00013     }
00014 }
00015 
00016 inline void N::binary_not(const N& a)
00017 {
00018     if(this_small)
00019     {
00020         reserve(0);
00021         limb = ~a.limb;
00022     }
00023     else
00024     {
00025         reserve(a.size);
00026         for(size_t i=0; i <= size; i++)
00027         {
00028             data[i] = ~a.data[i];
00029         }
00030     }
00031 }
00032 
00033 inline void N::binary_not()
00034 {
00035     if(this_small)
00036     {
00037         limb = ~limb;
00038     }
00039     else
00040     {
00041         for(size_t i=0; i <= size; i++)
00042         {
00043             data[i] = ~data[i];
00044         }
00045     }
00046 }
00047 
00048 inline void N::binary_and(const N& a, const N& b)
00049 {
00050     assert(a.size == b.size);
00051     if(is_small(a))
00052     {
00053         reserve(0);
00054         limb = a.limb & b.limb;
00055     }
00056     else
00057     {
00058         reserve(a.size);
00059         for(size_t i=0; i <= size; i++)
00060         {
00061             data[i] = a.data[i] & b.data[i];
00062         }
00063     }
00064 }
00065 
00066 inline void N::binary_and(const N& a)
00067 {
00068     assert(size == a.size);
00069     if(this_small)
00070     {
00071         limb &= a.limb;
00072     }
00073     else
00074     {
00075         for(size_t i=0; i <= size; i++)
00076         {
00077             data[i] &= a.data[i];
00078         }
00079     }
00080 }
00081 
00082 inline void N::binary_or(const N& a, const N& b)
00083 {
00084     assert(a.size == b.size);
00085     reserve(a.size);
00086     if(a.size)
00087     {
00088         for(size_t i=0; i <= size; i++)
00089         {
00090             data[i] = a.data[i] | b.data[i];
00091         }
00092     }
00093     else
00094     {
00095         limb = a.limb | b.limb;
00096     }
00097 }
00098 
00099 inline void N::binary_or(const N& a)
00100 {
00101     assert(size == a.size);
00102     if(size)
00103     {
00104         for(size_t i=0; i <= size; i++)
00105         {
00106             data[i] |= a.data[i];
00107         }
00108     }
00109     else
00110     {
00111         limb |= a.limb;
00112     }
00113 }
00114 
00115 inline void N::binary_xor(const N& a, const N& b)
00116 {
00117     assert(a.size == b.size);
00118     reserve(a.size);
00119     if(a.size)
00120     {
00121         for(size_t i=0; i <= size; i++)
00122         {
00123             data[i] = a.data[i] ^ b.data[i];
00124         }
00125     }
00126     else
00127     {
00128         limb = a.limb ^ b.limb;
00129     }
00130 }
00131 
00132 inline void N::binary_xor(const N& a)
00133 {
00134     assert(size == a.size);
00135     if(size)
00136     {
00137         for(size_t i=0; i <= size; i++)
00138         {
00139             data[i] ^= a.data[i];
00140         }
00141     }
00142     else
00143     {
00144         limb ^= a.limb;
00145     }
00146 }
00147 
00148 inline void N::left_shift(const N& a, unsigned int count)
00149 {
00150     if(fast_true(count))
00151     {
00152         if(a.size)
00153         {
00154             left_shift_large(a, count);
00155         }
00156         else
00157         {
00158             left_shift_small(a.limb, count);
00159         }
00160     }
00161 }
00162 
00163 inline void N::left_shift(unsigned int count)
00164 {
00165     if(fast_true(count))
00166     {
00167         if(this_small)
00168         {
00169             left_shift_small(count);
00170         }
00171         else
00172         {
00173             left_shift_large(count);
00174         }
00175     }
00176 }
00177 
00178 inline void N::right_shift(const N& a, unsigned int count)
00179 {
00180     if(fast_true(count))
00181     {
00182         if(a.size)
00183         {
00184             right_shift_large(a, count);
00185         }
00186         else
00187         {
00188             right_shift_small(a.limb, count);
00189         }
00190     }
00191 }
00192 
00193 inline void N::right_shift(unsigned int count)
00194 {
00195     if(fast_true(count))
00196     {
00197         if(size)
00198         {
00199             right_shift_large(count);
00200         }
00201         else
00202         {
00203             right_shift_small(count);
00204         }
00205     }
00206 }
00207 
00208 
00209 
00210 
00211 inline N operator&(const N& a, const N& b)
00212 {
00213     N r;
00214     r.binary_and(a, b);
00215     return r;
00216 }
00217 
00218 inline N operator|(const N& a, const N& b)
00219 {
00220     N r;
00221     r.binary_or(a, b);
00222     return r;
00223 }
00224 
00225 inline N operator<<(const N& a, unsigned int count)
00226 {
00227     N r;
00228     r.left_shift(a, count);
00229     return r;
00230 }
00231 
00232 inline N operator>>(const N& a, unsigned int count)
00233 {
00234     N r;
00235     r.right_shift(a, count);
00236     return r;
00237 }
00238 
00239 inline N& N::operator<<=(const limb_t count)
00240 {
00241     left_shift(count);
00242     return *this;
00243 }
00244 
00245 inline N& N::operator>>=(const limb_t count)
00246 {
00247     right_shift(count);
00248     return *this;
00249 }
00250 
00251 inline N& N::operator&=(const N& a)
00252 {
00253     binary_and(a);
00254     return *this;
00255 }
00256 
00257 inline N& N::operator|=(const N& a)
00258 {
00259     binary_or(a);
00260     return *this;
00261 }
00262 
00263 
00264 inline size_t N::two_multiplicity_large() const
00265 {
00266     size_t i;
00267     for(i=0; !data[i]; i++);
00268     return i * 64 + __builtin_ctzll(data[i]);
00269 }
00270 
00271 inline size_t N::two_multiplicity_small() const
00272 {
00273     return __builtin_ctzll(limb);
00274 }
00275 
00276 inline void N::left_shift_small(const limb_t a, unsigned int count)
00277 {
00278     size_t climbs = count / bits_per_limb;
00279     unsigned int cbits = count % bits_per_limb;
00280 
00281     limb_t lo = a << cbits;
00282     limb_t hi = a >> (bits_per_limb - cbits);
00283 
00284     if(climbs)
00285     {
00286         if(hi)
00287         {
00288             reserve(climbs + 1);
00289             for(size_t i=0; i < climbs; i++)
00290             {
00291                 data[i] = 0;
00292             }
00293             data[climbs] = lo;
00294             data[size] = hi;
00295         }
00296         else
00297         {
00298             reserve(climbs);
00299             for(size_t i=0; i < climbs; i++)
00300             {
00301                 data[i] = 0;
00302             }
00303             data[climbs] = lo;
00304         }
00305     }
00306     else
00307     {
00308         if(hi)
00309         {
00310             reserve(1);
00311             data[climbs] = lo;
00312             data[size] = hi;
00313         }
00314         else
00315         {
00316             reserve(0);
00317             limb = lo;
00318         }
00319     }
00320 }
00321 
00322 inline void N::left_shift_small(unsigned int count)
00323 {
00324     size_t climbs = count / bits_per_limb;
00325     unsigned int cbits = count % bits_per_limb;
00326 
00327     limb_t lo = limb << cbits;
00328     limb_t hi = (cbits) ? limb >> (bits_per_limb - cbits) : 0;
00329 
00330     if(climbs)
00331     {
00332         if(hi)
00333         {
00334             reserve(climbs + 1);
00335             for(size_t i=0; i < climbs; i++)
00336             {
00337                 data[i] = 0;
00338             }
00339             data[climbs] = lo;
00340             data[size] = hi;
00341         }
00342         else
00343         {
00344             reserve(climbs);
00345             for(size_t i=0; i < climbs; i++)
00346             {
00347                 data[i] = 0;
00348             }
00349             data[climbs] = lo;
00350         }
00351     }
00352     else
00353     {
00354         if(hi)
00355         {
00356             reserve(1);
00357             data[climbs] = lo;
00358             data[size] = hi;
00359         }
00360         else
00361         {
00362             reserve(0);
00363             limb = lo;
00364         }
00365     }
00366 }
00367 
00368 inline void N::right_shift_small(const limb_t a, unsigned int count)
00369 {
00370     reserve(0);
00371     limb = a >> count;
00372 }
00373 
00374 inline void N::right_shift_small(unsigned int count)
00375 {
00376     limb = limb >> count;
00377 }

Copyright © 2007-2008 Remco Bloemen.

Generated on Tue Jan 22 17:35:31 2008 for symbolism by doxygen 1.5.4

Hosted by SourceForge.net Logo