include/symbolism/N.Division.h

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

Hosted by SourceForge.net Logo