00001 #include <symbolism/N.h> 00002 00003 namespace symbolism { 00004 namespace ring { 00005 00006 // Multiplication algorithms 00007 void N::mul_large_large(const N& a, const N& b) 00008 { 00009 reserve(a.size + b.size + 1); 00010 if(a.size == b.size) 00011 { 00012 mpn_mul_n(data, a.data, b.data, a.size + 1); 00013 } 00014 else if(a.size > b.size) 00015 { 00016 mpn_mul(data, a.data, a.size + 1, b.data, b.size + 1); 00017 } 00018 else 00019 { 00020 mpn_mul(data, b.data, b.size + 1, a.data, a.size + 1); 00021 } 00022 normalize(); 00023 } 00024 00025 void N::mul_large_large(const N& a) 00026 { 00027 // Overlap is _not_ permitted, so make copies 00028 // TODO: Is copy constructor faster? Should look better! 00029 if(size == a.size) 00030 { 00031 size_t newsize = 2 * size + 1; 00032 void* space = malloc((newsize + 1) * sizeof(limb_t)); 00033 limb_t* newdata = reinterpret_cast<limb_t*>(space); 00034 mpn_mul_n(newdata, data, a.data, size + 1); 00035 free(data); 00036 data = newdata; 00037 size = newsize; 00038 } 00039 else if(size > a.size) 00040 { 00041 size_t newsize = size + a.size + 1; 00042 void* space = malloc((newsize + 1) * sizeof(limb_t)); 00043 limb_t* newdata = reinterpret_cast<limb_t*>(space); 00044 mpn_mul(newdata, data, size + 1, a.data, a.size + 1); 00045 free(data); 00046 data = newdata; 00047 size = newsize; 00048 } 00049 else 00050 { 00051 size_t newsize = size + a.size + 1; 00052 void* space = malloc((newsize + 1) * sizeof(limb_t)); 00053 limb_t* newdata = reinterpret_cast<limb_t*>(space); 00054 mpn_mul(newdata, a.data, a.size + 1, data, size + 1); 00055 free(data); 00056 data = newdata; 00057 size = newsize; 00058 } 00059 normalize(); 00060 } 00061 00062 void N::mul_large_small(const N& a, const limb_t b) 00063 { 00064 if(fast_true(b)) 00065 { 00066 reserve(a.size); 00067 limb_t carry; 00068 carry = mpn_mul_1(data, a.data, a.size + 1, b); 00069 add_carry_large(carry); 00070 } 00071 else 00072 { 00073 set(0); 00074 } 00075 } 00076 00077 void N::mul_large_small(const limb_t a) 00078 { 00079 if(fast_true(a)) 00080 { 00081 limb_t carry; 00082 carry = mpn_mul_1(data, data, size + 1, a); 00083 add_carry_large(carry); 00084 } 00085 else 00086 { 00087 set(0); 00088 } 00089 } 00090 00091 void N::mul_small_large(const N& a) 00092 { 00093 if(fast_true(limb)) 00094 { 00095 limb_t value = limb; 00096 reserve(a.size); 00097 limb_t carry; 00098 carry = mpn_mul_1(data, a.data, size + 1, value); 00099 add_carry_large(carry); 00100 } 00101 else 00102 { 00103 set(0); 00104 } 00105 } 00106 00107 }}
Copyright © 2007-2008 Remco Bloemen.
Generated on Tue Jan 22 17:35:31 2008 for symbolism by doxygen 1.5.4