src/N.Division.cpp

00001 #include <symbolism/N.h>
00002 
00003 namespace symbolism {
00004 namespace ring {
00005 
00006 void N::exact_div_large_large(const N& a, const N& b)
00007 {
00008     if(fast_false(a.size >= b.size))
00009     {
00010         throw "Inexact division!";
00011     }
00012     
00013     // Reserver space for the quotient
00014     reserve(a.size - b.size);
00015 
00016     // Allocate space for the remainder
00017     void* rem_space = malloc((b.size + 1) * sizeof(limb_t));
00018     limb_t* rem = reinterpret_cast<limb_t*>(rem_space);
00019     
00020     mpn_tdiv_qr(data, rem, 0, a.data, a.size + 1, b.data, b.size + 1);
00021 
00022     // Check the exactness
00023     for(size_t i=0; i <= b.size; i++)
00024     {
00025         if(rem[i])
00026         {
00027             throw "Inexact division!";
00028         }
00029     }
00030 
00031     free(rem);
00032 }
00033 
00034 void N::exact_div_large_large(const N& b)
00035 {
00036     /*
00037     if(fast_false(size >= b.size))
00038     {
00039     throw "Inexact division!";
00040 }
00041 
00042     void* rem_space = malloc((b.size + 1) * sizeof(limb_t));
00043     limb_t* rem = reinterpret_cast<limb_t*>(rem_space);
00044 
00045     void* quo_space = malloc((a.size - b.size + 1) * sizeof(limb_t));
00046     limb_t* quo = reinterpret_cast<limb_t*>(rem_space);
00047 
00048     mpn_tqdiv_qr(quo, rem, 0, data, size + 1, b.data, b.size + 1);
00049     free(data);
00050 
00051     // Check the exactness
00052     for(size_t i=0; i <= b.size; i++)
00053     {
00054     if(rem[i]])
00055     {
00056     throw "Inexact division!";
00057 }
00058 }
00059     free(rem);
00060     
00061     size = a.size - b.size;
00062     data = quo;
00063     */
00064 }
00065 
00066 void N::exact_div_large_small(const N& a, const limb_t b)
00067 {
00068     reserve(a.size);
00069     limb_t remainder;
00070     remainder = mpn_divrem_1(data, 0, a.data, a.size + 1, b);
00071     
00072     if(fast_false(remainder))
00073     {
00074         throw "Inexact division!";
00075     }
00076 }
00077 
00078 void N::exact_div_large_small(const limb_t b)
00079 {
00080     limb_t remainder;
00081     remainder = mpn_divrem_1(data, 0, data, size + 1, b);
00082     
00083     if(fast_false(remainder))
00084     {
00085         throw "Inexact division!";
00086     }
00087 }
00088 
00089 void N::div_large_large(N& rem, const N& a, const N& b)
00090 {
00091     if(a.size < b.size)
00092     {
00093         rem = a;
00094         set(0);
00095     }
00096     else
00097     {
00098         reserve(a.size - b.size);
00099         rem.reserve(b.size);
00100         mpn_tdiv_qr(data, rem.data, 0, a.data, a.size + 1, b.data, b.size + 1);
00101         normalize();
00102         rem.normalize();
00103     }
00104 }
00105 
00106 void N::div_large_small(N& rem, const N& a, const limb_t b)
00107 {
00108     reserve(a.size);
00109     rem = mpn_divrem_1(data, 0, a.data, a.size + 1, b);
00110     normalize();
00111 }
00112 
00113 void N::div_small_large(N& rem, const limb_t a, const N& b)
00114 {
00115     swap(*this, rem);
00116     set(0);
00117 }
00118 
00119 void N::div_large_large(N& rem, const N& a)
00120 {
00121     if(size < a.size)
00122     {
00123         swap(*this, rem);
00124         set(0);
00125     }
00126     else
00127     {
00128         N quo;
00129         quo.div_large_large(rem, *this, a);
00130         swap(*this, quo);
00131     }
00132 }
00133 
00134 void N::div_large_small(N& rem, const limb_t a)
00135 {
00136     rem = mpn_divrem_1(data, 0, data, size + 1, a);
00137     normalize();
00138 }
00139 
00140 void N::div_small_large(N& rem, const N& a)
00141 {
00142     swap(*this, rem);
00143     set(0);
00144 }
00145 
00146 void N::quo_large_large(const N& a, const N& b)
00147 {
00148     if(a.size < b.size)
00149     {
00150         set(0);
00151     }
00152     else
00153     {
00154         reserve(a.size - b.size);
00155         N rem;
00156         rem.reserve(b.size);
00157         mpn_tdiv_qr(data, rem.data, 0, a.data, a.size + 1, b.data, b.size + 1);
00158         normalize();
00159     }
00160 }
00161 
00162 void N::quo_large_small(const N& a, const limb_t b)
00163 {
00164     reserve(a.size);
00165     mpn_divrem_1(data, 0, a.data, a.size + 1, b);
00166     normalize();
00167 }
00168 
00169 void N::quo_small_large(const limb_t a, const N& b)
00170 {
00171     set(0);
00172 }
00173 
00174 void N::quo_large_large(const N& a)
00175 {
00176     if(size < a.size)
00177     {
00178         set(0);
00179     }
00180     else
00181     {
00182         N quo;
00183         quo.div_large_large(*this, a);
00184         swap(*this, quo);
00185     }
00186 }
00187 
00188 void N::quo_large_small(const limb_t a)
00189 {
00190     mpn_divrem_1(data, 0, data, size + 1, a);
00191     normalize();
00192 }
00193 
00194 void N::quo_small_large(const N& a)
00195 {
00196     set(0);
00197 }
00198 
00199 void N::rem_large_large(const N& a, const N& b)
00200 {
00201     if(a.size < b.size)
00202     {
00203         set(a);
00204     }
00205     else
00206     {
00207         N quo;
00208         quo.reserve(a.size - b.size);
00209         reserve(b.size);
00210         mpn_tdiv_qr(quo.limbs(), data, 0, a.data, a.size + 1, b.data, b.size + 1);
00211         normalize();
00212     }
00213 }
00214 
00215 void N::rem_large_small(const N& a, const limb_t b)
00216 {
00217     set(mpn_mod_1(a.data, a.size + 1, b));
00218 }
00219 
00220 void N::rem_small_large(const limb_t a, const N& b)
00221 {
00222     set(a);
00223 }
00224 
00225 void N::rem_large_large(const N& a)
00226 {
00227     if(size >= a.size)
00228     {
00229         N quo, rem;
00230         quo.div_large_large(rem, *this, a);
00231         swap(*this, rem);
00232     }
00233 }
00234 
00235 void N::rem_large_small(const limb_t a)
00236 {
00237     set(mpn_divrem_1(data, 0, data, size + 1, a));
00238 }
00239 
00240 void N::rem_small_large(const N& a)
00241 {
00242 }
00243 
00244 
00245 }}

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