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