00001 // 00002 // Division algorithm selectors 00003 // 00004 00005 inline void N::exact_div(const N& a, const N& b) 00006 { 00007 if(is_small(a)) 00008 { 00009 if(is_small(b)) 00010 { 00011 exact_div_small_small(a.limb, b.limb); 00012 } 00013 else 00014 { 00015 throw "Inexact division!"; 00016 } 00017 } 00018 else 00019 { 00020 if(is_small(b)) 00021 { 00022 exact_div_large_small(a, b.limb); 00023 } 00024 else 00025 { 00026 exact_div_large_large(a, b); 00027 } 00028 } 00029 } 00030 00031 inline void N::exact_div(const N& a) 00032 { 00033 if(this_small) 00034 { 00035 if(is_small(a)) 00036 { 00037 exact_div_small_small(a.limb); 00038 } 00039 else 00040 { 00041 throw "Inexact division!"; 00042 } 00043 } 00044 else 00045 { 00046 if(is_small(a)) 00047 { 00048 exact_div_large_small(a.limb); 00049 } 00050 else 00051 { 00052 exact_div_large_large(a); 00053 } 00054 }} 00055 00056 inline void N::div(N& rem, const N& a, const N& b) 00057 { 00058 if(is_small(a)) 00059 { 00060 if(is_small(b)) 00061 { 00062 div_small_small(rem, a.limb, b.limb); 00063 } 00064 else 00065 { 00066 div_small_large(rem, a.limb, b.limb); 00067 } 00068 } 00069 else 00070 { 00071 if(is_small(b)) 00072 { 00073 div_large_small(rem, a, b.limb); 00074 } 00075 else 00076 { 00077 div_large_large(rem, a, b); 00078 } 00079 } 00080 } 00081 00082 inline void N::div(N& rem, const N& a) 00083 { 00084 if(this_small) 00085 { 00086 if(is_small(a)) 00087 { 00088 div_small_small(rem, a.limb); 00089 } 00090 else 00091 { 00092 div_small_large(rem, a); 00093 } 00094 } 00095 else 00096 { 00097 if(is_small(a)) 00098 { 00099 div_large_small(rem, a.limb); 00100 } 00101 else 00102 { 00103 div_large_large(rem, a); 00104 } 00105 } 00106 } 00107 00108 inline void N::quo(const N& a, const N& b) 00109 { 00110 if(is_small(a)) 00111 { 00112 if(is_small(b)) 00113 { 00114 quo_small_small(a.limb, b.limb); 00115 } 00116 else 00117 { 00118 quo_small_large(a.limb, b.limb); 00119 } 00120 } 00121 else 00122 { 00123 if(is_small(b)) 00124 { 00125 quo_large_small(a, b.limb); 00126 } 00127 else 00128 { 00129 quo_large_large(a, b); 00130 } 00131 } 00132 } 00133 00134 inline void N::quo(const N& a) 00135 { 00136 if(this_small) 00137 { 00138 if(is_small(a)) 00139 { 00140 quo_small_small(a.limb); 00141 } 00142 else 00143 { 00144 quo_small_large(a); 00145 } 00146 } 00147 else 00148 { 00149 if(is_small(a)) 00150 { 00151 quo_large_small(a.limb); 00152 } 00153 else 00154 { 00155 quo_large_large(a); 00156 } 00157 } 00158 } 00159 00160 inline void N::rem(const N& a, const N& b) 00161 { 00162 if(is_small(a)) 00163 { 00164 if(is_small(b)) 00165 { 00166 rem_small_small(a.limb, b.limb); 00167 } 00168 else 00169 { 00170 rem_small_large(a.limb, b.limb); 00171 } 00172 } 00173 else 00174 { 00175 if(is_small(b)) 00176 { 00177 rem_large_small(a, b.limb); 00178 } 00179 else 00180 { 00181 rem_large_large(a, b); 00182 } 00183 } 00184 } 00185 00186 inline void N::rem(const N& a) 00187 { 00188 if(this_small) 00189 { 00190 if(is_small(a)) 00191 { 00192 rem_small_small(a.limb); 00193 } 00194 else 00195 { 00196 rem_small_large(a); 00197 } 00198 } 00199 else 00200 { 00201 if(is_small(a)) 00202 { 00203 rem_large_small(a.limb); 00204 } 00205 else 00206 { 00207 rem_large_large(a); 00208 } 00209 } 00210 } 00211 00212 // 00213 // Division operators 00214 // 00215 00216 inline N operator/(const N& a, const N& b) 00217 { 00218 N r; 00219 r.quo(a, b); 00220 return r; 00221 } 00222 00223 inline N& N::operator/=(const N& rhs) 00224 { 00225 quo(rhs); 00226 return *this; 00227 } 00228 00229 inline N operator%(const N& a, const N& b) 00230 { 00231 N r; 00232 r.rem(a, b); 00233 return r; 00234 } 00235 00236 inline N& N::operator%=(const N& rhs) 00237 { 00238 rem(rhs); 00239 return *this; 00240 } 00241 00242 inline N div(N& rem, const N& a, const N& b) 00243 { 00244 N quo; 00245 quo.div(rem, a, b); 00246 return quo; 00247 } 00248 00249 inline N div_exact(const N& a, const N& b) 00250 { 00251 N quo; 00252 quo.exact_div(a, b); 00253 return quo; 00254 } 00255 00256 inline N quo(const N& a, const N& b) 00257 { 00258 N quo; 00259 quo.quo(a, b); 00260 return quo; 00261 } 00262 00263 inline N rem(const N& a, const N& b) 00264 { 00265 N rem; 00266 rem.rem(a, b); 00267 return rem; 00268 } 00269 00270 // 00271 // Division algorithms 00272 // 00273 00274 inline void N::exact_div_small_small(const limb_t a, const limb_t b) 00275 { 00276 reserve(0); 00277 limb = a / b; 00278 00279 if(fast_false(a % b)) 00280 { 00281 throw "Inexact division!"; 00282 } 00283 } 00284 00285 inline void N::exact_div_small_small(const limb_t b) 00286 { 00287 if(fast_false(limb % b)) 00288 { 00289 throw "Inexact division!"; 00290 } 00291 00292 limb /= b; 00293 } 00294 00295 inline void N::div_small_small(N& rem, const limb_t a, const limb_t b) 00296 { 00297 set(a / b); 00298 rem = a % b; 00299 } 00300 00301 inline void N::div_small_small(N& rem, const limb_t b) 00302 { 00303 limb_t a = limb; 00304 limb = a / b; 00305 rem = a % b; 00306 } 00307 00308 inline void N::quo_small_small(const limb_t a, const limb_t b) 00309 { 00310 set(a / b); 00311 } 00312 00313 inline void N::quo_small_small(const limb_t a) 00314 { 00315 if(fast_true(a)) 00316 { 00317 limb /= a; 00318 } 00319 else 00320 { 00321 throw "Division by zero"; 00322 } 00323 } 00324 00325 inline void N::rem_small_small(const limb_t a, const limb_t b) 00326 { 00327 if(fast_true(b)) 00328 { 00329 set(a % b); 00330 } 00331 else 00332 { 00333 throw "Division by zero"; 00334 } 00335 } 00336 00337 inline void N::rem_small_small(const limb_t a) 00338 { 00339 if(fast_true(a)) 00340 { 00341 limb %= a; 00342 } 00343 else 00344 { 00345 throw "Division by zero"; 00346 } 00347 }
Copyright © 2007-2008 Remco Bloemen.
Generated on Tue Jan 22 17:35:31 2008 for symbolism by doxygen 1.5.4