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